.NET e le... "riflessioni sugli attributi" :-)

Avete presente quando venite assaliti da un dubbio e (quasi) non riuscite a pensare ad altro? Ecco: immaginate che il dubbio riguardi una funzionalità di .NET e che MSDN non sia esaustivo al riguardo, immaginate che anche Raf (cui ho rotto le @@ via messenger) non vi sappia dare una risposta al volo... Concorderete con me che è uno di quei casi nei quali ci si sente *obbligati* a "mettere in piedi" un esempietto per: vedere, capire, ....SAPERE. Vaorainonda, il reality show: "Vita da Saltarello: riflessioni sugli attributi" (si, il doppio senso ambiguo carpiato è voluto ).

La causa scatenante di cotanto post è la domanda: "ma il metodo GetCustomAttributes() può restituire una *famiglia* di attributi?" Mi spiego meglio: molte classi tipiche della Reflection implementano l'interfaccia ICustomAttributeProvider, che espone una forma in overload del suddetto metodo avente la firma:

 GetCustomAttributes( System.Type attributeType , System.Boolean inherit )

Posso quindi specificare l'istanza di Type che qualifica una tipologia di attributo e sapere se il tipo o membro oggetto della mia "riflessione" sia stato decorato da esso (ricordiamoci che è possibile -dipendentemente dall'attributo- effettuare una decorazione multipla dello stesso tipo). La mia domanda, quindi è: "Mi saranno restituiti *solo* gli attributi di tipo attributeType o anche quelli di tipi da esso derivati?" (comodo se state creando una famiglia di classi attributo e del codice polimorfico che se ne avvale). Purtroppo, la documentazione del suddetto metodo in MSDN Library non menziona questo comportamento, quindi una verifica era d'obbligo. Ecco quindi un paio di attributi creati per l'occasione:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public abstract class BaseAttribute : Attribute
{
}

public class MyAttribute : BaseAttribute
{

}

public class MyClass
{
   private string property;

   [MyAttribute()]
   public string Field;

   [MyAttribute()]
   public string Property
   {
       get
       {
           return property;
       }
       set
      {
           property = value;
      }
   }
}

Infine, proviamo a analizzare il nostro codice mediante un "tocco" di reflection:

MyClass o = new MyClass();
Type objectType = o.GetType();
MemberInfo[] members = objectType.GetMembers();
foreach(MemberInfo member in members)
{
    Attribute[] attributes = (Attribute[]) member.GetCustomAttributes(typeof(BaseAttribute), true);
    foreach(Attribute attr in attributes)
    {
        Console.WriteLine(attr.GetType().Name);
    }
}

Ed ecco il responso finale:

MyAttribute
MyAttribute

Ora lo sappiamo: GetCustomAttributes può essere utilizzata per ottenere una famiglia di attributi. :-)

«luglio»
domlunmarmergiovensab
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456