Respostas:
Os atributos terão uma matriz. Porém, se você controlar o atributo, também poderá usar params
(o que é mais agradável para os consumidores, IMO):
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(params int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(3, 4, 5)]
class MyClass { }
Acontece que sua sintaxe para a criação de array está errada:
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
Você pode fazer isso, mas não é compatível com CLS:
[assembly: CLSCompliant(true)]
class Foo : Attribute
{
public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}
Programas:
Warning 1 Arrays as attribute arguments is not CLS-compliant
Para uso de reflexão regular, pode ser preferível ter vários atributos, ou seja,
[Foo("abc"), Foo("def")]
No entanto, isso não funcionará com TypeDescriptor
/ PropertyDescriptor
, onde apenas uma única instância de qualquer atributo é suportada (a primeira ou a última vence, não consigo lembrar qual).
Tente declarar o construtor assim:
public class MyCustomAttribute : Attribute
{
public MyCustomAttribute(params int[] t)
{
}
}
Então você pode usá-lo como:
[MyCustomAttribute(3, 4, 5)]
Isso deve ficar bem. A partir das especificações, seção 17.2:
Uma expressão E é uma expressão de argumento de atributo se todas as seguintes afirmações forem verdadeiras:
Aqui está um exemplo:
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
{
}
Sim, mas você precisa inicializar o array que está passando. Aqui está um exemplo de um teste de linha em nossos testes de unidade que testa um número variável de opções de linha de comando;
[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
Para pegar carona na resposta de Marc Gravell, sim, você pode definir um atributo com parâmetros de matriz, mas aplicar um atributo com um parâmetro de matriz não é compatível com CLS. No entanto, apenas definir um atributo com uma propriedade de array é perfeitamente compatível com CLS.
O que me fez perceber isso foi que Json.NET, uma biblioteca compatível com CLS, tem uma classe de atributo JsonPropertyAttribute com uma propriedade chamada ItemConverterParameters que é uma matriz de objetos.