Risposte:
Gli attributi prenderanno un array. Sebbene tu controlli l'attributo, puoi anche usare params
invece (che è più carino per i consumatori, IMO):
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(params int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(3, 4, 5)]
class MyClass { }
La tua sintassi per la creazione di array è semplicemente disattivata:
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
public MyCustomAttribute(int[] values) {
this.Values = values;
}
}
[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
Puoi farlo, ma non è conforme a CLS:
[assembly: CLSCompliant(true)]
class Foo : Attribute
{
public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}
Spettacoli:
Warning 1 Arrays as attribute arguments is not CLS-compliant
Per un uso regolare della riflessione, potrebbe essere preferibile avere più attributi, ad es
[Foo("abc"), Foo("def")]
Tuttavia, questo non funzionerà con TypeDescriptor
/ PropertyDescriptor
, dove è supportata solo una singola istanza di qualsiasi attributo (la prima o l'ultima vince, non ricordo quale).
Prova a dichiarare il costruttore in questo modo:
public class MyCustomAttribute : Attribute
{
public MyCustomAttribute(params int[] t)
{
}
}
Quindi puoi usarlo come:
[MyCustomAttribute(3, 4, 5)]
Dovrebbe essere ok. Dalle specifiche, sezione 17.2:
Un'espressione E è un'espressione di attributo-argomento se tutte le seguenti affermazioni sono vere:
Ecco un esempio:
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
{
}
Sì, ma è necessario inizializzare l'array che si sta passando. Di seguito è riportato un esempio di un test di riga nei nostri test unitari che verifica un numero variabile di opzioni della riga di comando;
[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
Per tornare sulla risposta di Marc Gravell, sì, puoi definire un attributo con parametri di matrice ma l'applicazione di un attributo con un parametro di matrice non è conforme a CLS. Tuttavia, la semplice definizione di un attributo con una proprietà array è perfettamente conforme a CLS.
Ciò che mi ha fatto capire questo è stato che Json.NET, una libreria conforme a CLS, ha una classe di attributi JsonPropertyAttribute con una proprietà denominata ItemConverterParameters che è un array di oggetti.