Come lavorare con gli attributi in C #

Gli attributi sono una potente funzionalità nel linguaggio di programmazione C # che può aggiungere informazioni sui metadati agli assembly.

Un attributo è in realtà un oggetto associato a uno qualsiasi di questi elementi: Assembly, Class, Method, Delegate, Enum, Event, Field, Interface, Property e Struct. Possono essere utilizzati per associare informazioni dichiarative: è possibile recuperare tali informazioni in fase di esecuzione in un secondo momento, se necessario, utilizzando la reflection. In altre parole, puoi usare gli attributi per inserire informazioni aggiuntive negli assembly che possono essere interrogate in fase di esecuzione, se necessario, usando la reflection. Un attributo comprende il suo nome e, facoltativamente, un elenco di parametri. Il nome dell'attributo corrisponde alla classe dell'attributo.

È possibile sfruttare gli attributi per convalidare gli oggetti di business nella propria applicazione. Esistono due tipi di attributi: attributi intrinseci e attributi personalizzati. Mentre il primo è disponibile come parte del framework .Net, il secondo può essere implementato derivando una classe dalla classe System.Attribute. Il MSDN afferma: "Un attributo è una parte di ulteriori informazioni dichiarative specificate per una dichiarazione."

Entriamo ora nel codice. L'attributo Obsolete può essere utilizzato per indicare un metodo come obsoleto, uno che non dovrebbe più essere utilizzato poiché non è più necessario o potrebbe avere qualche altra alternativa. Il frammento di codice seguente illustra come utilizzare l'attributo Obsolete sopra una dichiarazione di metodo.

[Obsolete("This method is obsolete...")]

        public static void DoSomeWork()

        {

            //Some code

        }

Se si utilizza questo metodo nel codice e si compila il programma, verrà visualizzato un avviso nella finestra di output dell'IDE di Visual Studio. Quindi, puoi ignorare questo avviso se lo desideri. Ora, cosa succede se vuoi che i tuoi sviluppatori non utilizzino affatto questo metodo? Bene, puoi quindi utilizzare il secondo parametro (è facoltativo) mentre dichiari l'attributo Obsoleto. Ecco la versione modificata del metodo DoSomeWork (). Notare l'utilizzo del parametro booleano questa volta.

[Obsolete("This method is obsolete...", true)]

        public static void DoSomeWork()

        {

                       //Some code

        }                                                                                                                        

Quando questa volta si passa "true" come secondo parametro opzionale e si compila il programma, il codice non viene compilato affatto. È quello che volevi fare, non è vero?

Attributi personalizzati

In questa sezione esploreremo come possiamo implementare attributi personalizzati. Gli attributi personalizzati sono classi che ereditano la classe System.Attribute. Quindi, per implementare una classe di attributi personalizzati, creare una nuova classe e derivarla dalla classe System.Attribute come mostrato di seguito.

using System;

public class CustomAttribute : Attribute

{

}

Per controllare l'utilizzo degli attributi personalizzati, puoi sfruttare la classe AttributeUsage. Questa classe contiene proprietà come ValidOn, AllowMultiple e Inherited che possono essere utilizzate per controllare l'utilizzo dell'attributo personalizzato.

Il seguente frammento di codice illustra una versione modificata della nostra classe di attributi personalizzati. Notare l'utilizzo di un costruttore che accetta una stringa come argomento e la assegna al membro della stringa privata della classe. Questo è solo a scopo illustrativo.

[AttributeUsage(AttributeTargets.All)]

    public class CustomAttribute : Attribute

    {

        private string text;

        public CustomAttribute(string text)

        {

            this.Text = text;

        }

        public string Text

        {

            get

            {

                return this.text;

            }

            set

            {

                this.text = value;

            }

        }

    }

Puoi anche specificare le destinazioni dell'attributo a cui applicare l'attributo personalizzato. Ecco come puoi farlo.

[AttributeUsage(AttributeTargets.Class |

AttributeTargets.Constructor |

AttributeTargets.Field |

AttributeTargets.Method |

AttributeTargets.Property,

AllowMultiple = true)]

    public class CustomAttribute : Attribute

    {

        private string text;

        public CustomAttribute(string text)

        {

            this.Text = text;

        }

        public string Text

        {

            get

            {

                return this.text;

            }

            set

            {

                this.text = value;

            }

        }

    }

È ora possibile utilizzare la riflessione per visualizzare tutti gli attributi applicati a un particolare oggetto utilizzando il seguente frammento di codice.

MemberInfo memberInfo = typeof(CustomAttribute);

object[] attributes = memberInfo.GetCustomAttributes(true);

for (int i = 0, j = attributes.Length; i < j; i++)

  {

     Console.WriteLine(attributes[i]);

  }

Consideriamo ora la seguente classe alla quale applicheremo il nostro attributo personalizzato.

[CustomAttribute("Hello World...")]

public class SomeClass

{

}

Nota come è stato utilizzato l'attributo personalizzato e come argomento è stato passato un testo. Il frammento di codice seguente illustra come stampare il contenuto della proprietà Text.

MemberInfo memberInfo = typeof(SomeClass);

object[] attributes = memberInfo.GetCustomAttributes(true);

foreach (object attribute in attributes)

{

CustomAttribute customAttribute = attribute as CustomAttribute;

if (customAttribute != null)

Console.WriteLine("Text = {0}", customAttribute.Text);

else

Console.WriteLine();

}