2012-01-18 17 views
8

Questi sono i modelli più comuni e solo io ne ho visto finora:Quale sintassi è consentita quando si applicano gli attributi C#?

[AttributeFoo] 
[AttributeBar("Hello world!")] 
[AttributeBaz(foo=42,bar="Hello world!")] 
public class Example {} 

La sintassi dell'attributo assomiglia si sta chiamando un costruttore. E prima che C# supportasse argomenti facoltativi e denominati, i parametri denominati per gli attributi erano l'unica differenza visibile.

Il compilatore C# consente qualcos'altro? Come gli argomenti params o gli inizializzatori di oggetti/raccolte?

Consulta anche: Applying Attributes su MSDN sono tenuti

+0

Una volta ho messo un inizializzatore 'stringa []' in un attributo. – JohnL

risposta

3

AFAIK, i parametri denominati consentono solo tipi interi. Sfortunatamente non ho un riferimento a questo, l'ho solo imparato attraverso la mia stessa sperimentazione.

Quando si tenta di utilizzare inizializzatori oggetto, ho ottenuto questo errore dal compilatore:

Un argomento attributo deve essere un'espressione costante, typeof espressione o creazione matrice espressione di un tipo di parametro di attributo

Anche se questo documentation è vecchia di qualche anno, ha le informazioni di riferimento che cercavo:

attributo p arametri sono limitati a valori costanti dei seguenti tipi:

  • tipi semplici (bool, byte, char, short, int, long, float, e doppie)
  • stringa
  • System.Type
  • enums
  • oggetto (l'argomento di un parametro di attributo di tipo oggetto deve essere un valore costante di uno dei tipi precedenti.) Monodimensionali array di qualsiasi tipo di cui sopra

Così funziona:

//Test attribute class 
[AttributeUsage(AttributeTargets.All)] 
internal class TestAttribute : Attribute 
{ 
    public int[] Something { get; set; } 
} 

//Using an array initialiser - an array of integers 
[TestAttribute(Something = new int[]{1, 2, 3, 4, 5})] 
public abstract class Something 

considerando che il presente non lo farei:

//Test person class 
internal class Person 
{ 
    public string Name { get; set; } 

    public Person(string name) 
    { 
     this.Name = name; 
    } 
} 

//Test attribute class 
[AttributeUsage(AttributeTargets.All)] 
internal class TestAttribute : Attribute 
{ 
    public IEnumerable<Person> Something { get; set; } 
} 

//This won't work as Person is not an integral type 
[TestAttribute(Something = new Person[]{new Person("James")})] 

EDIT: solo per elaborare, gli attributi fanno parte dei metadati per i costrutti a cui sono applicati (all'interno dell'IL generato), quindi i membri della classe attribute devono essere determinati al momento della compilazione; da qui la restrizione sui parametri degli attributi ai valori costanti.

0

parametri posizionali e devono venire prima di qualsiasi parametro di nome; corrispondono ai parametri di uno dei costruttori dell'attributo. I parametri nominati sono opzionali e corrispondono alle proprietà di lettura/scrittura dell'attributo. In C++, C# e J #, specificare nome = valore per ogni parametro facoltativo, dove nome è il nome della proprietà. In Visual Basic, specificare il nome: = valore.

Dal link fornito. Sembra che siano le uniche cose consentite. Fondamentalmente stai combinando il costruttore con la logica di inizializzazione delle proprietà incorporate, come hai detto.

3

In aggiunta a ciò che altri hanno detto, vorrei sottolineare che gli attributi possono anche essere separati da virgole.

[AttributeFoo, AttributeBar("Hello world!"), AttributeBaz(foo=42,bar="Hello world!")] 
public class Example {} 
+2

Questa è una cattiva pratica; è meno leggibile. – Jowen

Problemi correlati