2008-11-06 13 views

Respuesta

142

Los atributos tomarán una matriz. Aunque si controlas el atributo, también se puede utilizar params lugar (que es más agradable para los consumidores, OMI):

class MyCustomAttribute : Attribute { 
    public int[] Values { get; set; } 

    public MyCustomAttribute(params int[] values) { 
     this.Values = values; 
    } 
} 

[MyCustomAttribute(3, 4, 5)] 
class MyClass { } 

Su sintaxis de creación de la matriz sólo pasa a estar fuera:

class MyCustomAttribute : Attribute { 
    public int[] Values { get; set; } 

    public MyCustomAttribute(int[] values) { 
     this.Values = values; 
    } 
} 

[MyCustomAttribute(new int[] { 3, 4, 5 })] 
class MyClass { } 
4

Sí, pero hay que inicializar la matriz que está pasando en Este es un ejemplo de una prueba de fila en nuestras pruebas de unidad que pone a prueba un número variable de opciones de línea de comandos. ;

[Row(new[] { "-l", "/port:13102", "-lfsw" })] 
public void MyTest(string[] args) { //... } 
12

Eso debería estar bien. A partir de la especificación, la sección 17.2:

Una expresión E es un atributo -argumento-expresión si todas las siguientes afirmaciones son ciertas:

  • El tipo de E es un tipo de parámetro de atributo (§17.1 .3).
  • en tiempo de compilación, el valor de E se pueden resolver a uno de los siguientes:
    • un valor constante.
    • Un objeto System.Type.
    • Una matriz unidimensional de atributo-argumento-expresiones.

He aquí un ejemplo:

using System; 

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] 
public class SampleAttribute : Attribute 
{ 
    public SampleAttribute(int[] foo) 
    { 
    } 
} 

[Sample(new int[]{1, 3, 5})] 
class Test 
{ 
} 
+3

Tenga cuidado con el cumplimiento de CLS, aunque –

16

Trate declarar el constructor de esta manera:

public class MyCustomAttribute : Attribute 
{ 
    public MyCustomAttribute(params int[] t) 
    { 
    } 
} 

A continuación, puede utilizarlo como:

[MyCustomAttribute(3, 4, 5)]

1

Puedes hacer eso. Otro ejemplo podría ser:

class MyAttribute: Attribute 
{ 
    public MyAttribute(params object[] args) 
    { 
    } 
} 

[MyAttribute("hello", 2, 3.14f)] 
class Program 
{ 
    static void Main(string[] args) 
    { 
    } 
} 
30

Puede hacerlo, pero no es compatible con CLS:

[assembly: CLSCompliant(true)] 

class Foo : Attribute 
{ 
    public Foo(string[] vals) { } 
} 
[Foo(new string[] {"abc","def"})] 
static void Bar() {} 

Shows:

Warning 1 Arrays as attribute arguments is not CLS-compliant 

Para el uso de reflexión regular, puede ser preferible tener múltiples atributos, es decir

[Foo("abc"), Foo("def")] 

Sin embargo, esto no funcionará con TypeDescriptor/PropertyDescriptor, en donde sólo se admite una única instancia de cualquier atributo (ya sea el primero o el último victorias, no recuerdo cuál).

+3

nota: múltiples atributos requieren un atributo AttributeUsage en su atributo. http://stackoverflow.com/questions/553540/how-to-create-duplicate-allowed-attribute – russau

1

Para aprovechar la respuesta de Marc Gravell, sí puede definir un atributo con parámetros de matriz, pero aplicar un atributo con un parámetro de matriz no es compatible con CLS. Sin embargo, solo definir un atributo con una propiedad de matriz es perfectamente compatible con CLS.

Lo que me hizo darme cuenta de esto fue que Json.NET, una biblioteca compatible con CLS, tiene una clase de atributo JsonPropertyAttribute con una propiedad llamada ItemConverterParameters que es una matriz de objetos.

Cuestiones relacionadas