Condividi tramite


Recupero di informazioni memorizzate negli attributi

Il recupero di un attributo personalizzato è un'operazione semplice. Dichiarare innanzitutto un'istanza dell'attributo che si desidera recuperare. Utilizzare quindi il metodo Attribute.GetCustomAttribute per inizializzare il nuovo attributo sul valore dell'attributo da recuperare. Al termine dell'inizializzazione del nuovo attributo sarà sufficiente utilizzarne le proprietà per ottenere i valori.

Nota importanteImportante

In questo argomento viene descritto come recuperare gli attributi per il codice caricato nel contesto di esecuzione.Per recuperare gli attributi per il codice caricato nel contesto di sola reflection, è necessario utilizzare la classe CustomAttributeData, come illustrato in Procedura: caricare assembly nel contesto Reflection-Only.

In questa sezione verranno descritti i seguenti metodi per il recupero degli attributi:

  • Recupero di una singola istanza di un attributo

  • Recupero di più istanze di un attributo applicate allo stesso ambito

  • Recupero di più istanze di un attributo applicate ad ambiti diversi

Recupero di una singola istanza di un attributo

Nell'esempio che segue l'attributo DeveloperAttribute, descritto nella sezione precedente, viene applicato a livello della classe MainApp. Nel metodo GetAttribute si utilizza GetCustomAttribute per recuperare a livello di classe i valori memorizzati in DeveloperAttribute prima di visualizzarli nella console.

Imports System
Imports System.Reflection
Imports CustomCodeAttributes

<Developer("Joan Smith", "42", Reviewed := True)>
Class MainApp
    Public Shared Sub Main()
        ' Call function to get and display the attribute.
        GetAttribute(GetType(MainApp))
    End Sub

    Public Shared Sub GetAttribute(t As Type)
        ' Get instance of the attribute.
        Dim MyAttribute As DeveloperAttribute =
            CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)

        If MyAttribute Is Nothing Then
            Console.WriteLine("The attribute was not found.")
        Else
            ' Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttribute.Name)
            ' Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttribute.Level)
            ' Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}." , MyAttribute.Reviewed)
        End If
    End Sub
End Class
using System;
using System.Reflection;
using CustomCodeAttributes;

[Developer("Joan Smith", "42", Reviewed = true)]
class MainApp
{
    public static void Main()
    {
        // Call function to get and display the attribute.
        GetAttribute(typeof(MainApp));
    }

    public static void GetAttribute(Type t)
    {
        // Get instance of the attribute.
        DeveloperAttribute MyAttribute =
            (DeveloperAttribute) Attribute.GetCustomAttribute(t, typeof (DeveloperAttribute));

        if (MyAttribute == null)
        {
            Console.WriteLine("The attribute was not found.");
        }
        else
        {
            // Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttribute.Name);
            // Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttribute.Level);
            // Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}." , MyAttribute.Reviewed);
        }
    }
}
using namespace System;
using namespace System::Reflection;
using namespace CustomCodeAttributes;

[Developer("Joan Smith", "42", Reviewed = true)]
ref class MainApp
{
public:
    static void Main()
    {
        // Call function to get and display the attribute.
        GetAttribute(MainApp::typeid);
    }

    static void GetAttribute(Type^ t)
    {
        // Get instance of the attribute.
        DeveloperAttribute^ MyAttribute =
            (DeveloperAttribute^) Attribute::GetCustomAttribute(t, DeveloperAttribute::typeid);

        if (MyAttribute == nullptr)
        {
            Console::WriteLine("The attribute was not found.");
        }
        else
        {
            // Get the Name value.
            Console::WriteLine("The Name Attribute is: {0}." , MyAttribute->Name);
            // Get the Level value.
            Console::WriteLine("The Level Attribute is: {0}." , MyAttribute->Level);
            // Get the Reviewed value.
            Console::WriteLine("The Reviewed Attribute is: {0}." , MyAttribute->Reviewed);
        }
    }
};

All'esecuzione di questo programma viene visualizzato il seguente testo.

The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.

Se non è possibile individuare l'attributo, MyAttribute verrà inizializzato sul valore Null. In questo esempio viene verificata la presenza di un'istanza di MyAttribute e l'utente viene informato qualora non venisse individuato alcun attributo. Se non è possibile trovare l'attributo DeveloperAttribute nell'ambito della classe, nella console verrà visualizzato il seguente messaggio:

The attribute was not found. 

In questo esempio si presuppone che la definizione dell'attributo sia contenuta nello spazio dei nomi corrente. Importare lo spazio dei nomi in cui si trova la definizione dell'attributo se non si tratta dello spazio dei nomi corrente.

Recupero di più istanze di un attributo applicate allo stesso ambito

Nell'esempio precedente la classe da analizzare e l'attributo specifico da trovare vengono passati a GetCustomAttribute. Tale codice funziona correttamente solo se a livello di classe viene applicata un'unica istanza di un attributo. Se vengono invece applicate più istanze di uno stesso attributo a livello della stessa classe il metodo GetCustomAttribute non è in grado di recuperare tutte le informazioni. Nei casi in cui più istanze dello stesso attributo vengono applicate al medesimo ambito è possibile utilizzare Attribute.GetCustomAttributes per inserire tutte le istanze di un attributo in una matrice. Se ad esempio due istanze di DeveloperAttribute sono applicate a livello di classe per la stessa classe, sarà possibile modificare il metodo GetAttribute in modo da visualizzare le informazioni presenti in entrambi gli attributi. Per applicare più attributi allo stesso livello, è necessario che l'attributo sia definito con la proprietà AllowMultiple impostata su true in AttributeUsageAttribute.

Nell'esempio di codice riportato di seguito si illustra come utilizzare il metodo GetCustomAttributes per creare una matrice che faccia riferimento a tutte le istanze di DeveloperAttribute in qualsiasi classe fornita. I valori di tutti gli attributi verranno quindi visualizzati nella console.

Public Shared Sub GetAttribute(t As Type)
    Dim MyAttributes() As DeveloperAttribute =
        CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

    If MyAttributes Is Nothing Then
        Console.WriteLine("The attribute was not found.")
    Else
        For i As Integer = 0 To MyAttributes.Length - 1
            ' Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttributes(i).Name)
            ' Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttributes(i).Level)
            ' Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes(i).Reviewed)
        Next i
    End If
End Sub
public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttributes =
        (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

    if (MyAttributes == null)
    {
        Console.WriteLine("The attribute was not found.");
    }
    else
    {
        for (int i = 0 ; i < MyAttributes.Length ; i++)
        {
            // Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttributes[i].Name);
            // Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttributes[i].Level);
            // Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i].Reviewed);
        }
    }
}
public:
    static void GetAttribute(Type^ t)
    {
        array<DeveloperAttribute^>^ MyAttributes =
            (array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);

        if (MyAttributes == nullptr)
        {
            Console::WriteLine("The attribute was not found.");
        }
        else
        {
            for (int i = 0 ; i < MyAttributes->Length; i++)
            {
                // Get the Name value.
                Console::WriteLine("The Name Attribute is: {0}." , MyAttributes[i]->Name);
                // Get the Level value.
                Console::WriteLine("The Level Attribute is: {0}." , MyAttributes[i]->Level);
                // Get the Reviewed value.
                Console::WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i]->Reviewed);
            }
        }
    }

Se non viene individuato alcun attributo verrà generato un messaggio di avviso. In caso contrario verranno visualizzate le informazioni contenute in entrambe le istanze di DeveloperAttribute.

Recupero di più istanze di un attributo applicate ad ambiti diversi

I metodi GetCustomAttributes e GetCustomAttribute non effettuano ricerche in un'intera classe per restituire tutte le istanze di un attributo presenti nella classe. Questi metodi consentono invece di eseguire ricerche all'interno di un unico metodo o membro alla volta. Se si utilizza una classe in cui lo stesso attributo è applicato a ciascun membro e si desidera recuperare i valori di tutti gli attributi applicati ai membri è necessario specificare in GetCustomAttributes e GetCustomAttribute ogni metodo o membro singolarmente.

Nell'esempio di codice riportato di seguito viene accettata una classe come parametro e viene effettuata la ricerca dell'attributo DeveloperAttribute definito in precedenza, a livello di classe e per ciascun singolo metodo della classe.

Public Shared Sub GetAttribute(t As Type)
    Dim att As DeveloperAttribute

    ' Get the class-level attributes.

    ' Put the instance of the attribute on the class level in the att object.
    att = CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)

    If att Is Nothing
        Console.WriteLine("No attribute in class {0}.\n", t.ToString())
    Else
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name)
        Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level)
        Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed)
    End If

    ' Get the method-level attributes.

    ' Get all methods in this class, and put them
    ' in an array of System.Reflection.MemberInfo objects.
    Dim MyMemberInfo() As MemberInfo = t.GetMethods()

    ' Loop through all methods in this class that are in the
    ' MyMemberInfo array.
    For i As Integer = 0 To MyMemberInfo.Length - 1
        att = CType(Attribute.GetCustomAttribute(MyMemberInfo(i), _
            GetType(DeveloperAttribute)), DeveloperAttribute)
        If att Is Nothing Then
            Console.WriteLine("No attribute in member function {0}.\n" , MyMemberInfo(i).ToString())
        Else
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.",
                MyMemberInfo(i).ToString(), att.Name)
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.",
                MyMemberInfo(i).ToString(), att.Level)
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
                MyMemberInfo(i).ToString(), att.Reviewed)
        End If
    Next
End Sub
public static void GetAttribute(Type t)
{
    DeveloperAttribute att;

    // Get the class-level attributes.

    // Put the instance of the attribute on the class level in the att object.
    att = (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof (DeveloperAttribute));

    if (att == null)
    {
        Console.WriteLine("No attribute in class {0}.\n", t.ToString());
    }
    else
    {
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name);
        Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level);
        Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed);
    }

    // Get the method-level attributes.

    // Get all methods in this class, and put them
    // in an array of System.Reflection.MemberInfo objects.
    MemberInfo[] MyMemberInfo = t.GetMethods();

    // Loop through all methods in this class that are in the
    // MyMemberInfo array.
    for (int i = 0; i < MyMemberInfo.Length; i++)
    {
        att = (DeveloperAttribute) Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));
        if (att == null)
        {
            Console.WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i].ToString());
        }
        else
        {
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.",
                MyMemberInfo[i].ToString(), att.Name);
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.",
                MyMemberInfo[i].ToString(), att.Level);
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
                MyMemberInfo[i].ToString(), att.Reviewed);
        }
    }
}
public:
    static void GetAttribute(Type^ t)
    {
        DeveloperAttribute^ att;

        // Get the class-level attributes.

        // Put the instance of the attribute on the class level in the att object.
        att = (DeveloperAttribute^) Attribute::GetCustomAttribute (t, DeveloperAttribute::typeid);

        if (att == nullptr)
        {
            Console::WriteLine("No attribute in class {0}.\n", t->ToString());
        }
        else
        {
            Console::WriteLine("The Name Attribute on the class level is: {0}.", att->Name);
            Console::WriteLine("The Level Attribute on the class level is: {0}.", att->Level);
            Console::WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att->Reviewed);
        }

        // Get the method-level attributes.

        // Get all methods in this class, and put them
        // in an array of System.Reflection.MemberInfo objects.
        array<MemberInfo^>^ MyMemberInfo = t->GetMethods();

        // Loop through all methods in this class that are in the
        // MyMemberInfo array.
        for (int i = 0; i < MyMemberInfo->Length; i++)
        {
            att = (DeveloperAttribute^) Attribute::GetCustomAttribute(MyMemberInfo[i], DeveloperAttribute::typeid);
            if (att == nullptr)
            {
                Console::WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i]->ToString());
            }
            else
            {
                Console::WriteLine("The Name Attribute for the {0} member is: {1}.",
                    MyMemberInfo[i]->ToString(), att->Name);
                Console::WriteLine("The Level Attribute for the {0} member is: {1}.",
                    MyMemberInfo[i]->ToString(), att->Level);
                Console::WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
                    MyMemberInfo[i]->ToString(), att->Reviewed);
            }
        }
    }

Se non viene individuata alcuna istanza di DeveloperAttribute a livello di metodo o di classe, l'utente verrà informato dal metodo GetAttribute che non è stato trovato alcun attributo e verrà visualizzato il nome del metodo o della classe in cui l'attributo non è presente. Se viene invece individuato un attributo, nella console verranno visualizzati i campi Name, Level e Reviewed.

È possibile utilizzare i membri della classe Type per accedere ai singoli metodi e membri della classe passata. Nell'esempio viene innanzitutto eseguita una query all'oggetto Type per ottenere informazioni sull'attributo a livello di classe. Viene quindi utilizzato Type.GetMethods per inserire le istanze di tutti i metodi in una matrice di oggetti System.Reflection.MemberInfo al fine di recuperare le informazioni sugli attributi a livello di metodo. È inoltre possibile utilizzare il metodo Type.GetProperties per cercare eventuali attributi a livello di proprietà o il metodo Type.GetConstructors per cercare eventuali attributi a livello di costruttore.

Vedere anche

Riferimenti

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

Concetti

Estensione di metadati mediante attributi