Abrufen von Informationen aus Attributen

Das Abrufen eines benutzerdefinierten Attributs ist ein einfacher Prozess. Zuerst deklarieren Sie eine Instanz des Attributs, das Sie abrufen möchten. Dann verwenden Sie die Attribute.GetCustomAttribute-Methode, um das neue Attribut auf den Wert des abzurufenden Attributs zu initialisieren. Sobald das neue Attribut initialisiert wurde, können Sie dessen Eigenschaften verwenden, um die Werte abzurufen.

Wichtig

In diesem Artikel wird beschrieben, wie Attribute für Code abgerufen werden, der in den Ausführungskontext geladen wird. Zum Abrufen von Attributen für Code, der in den reflexionsbezogenen Kontext geladen wurde, müssen Sie die CustomAttributeData-Klasse verwenden, wie in Vorgehensweise: Laden von Assemblys in den reflexionsbezogenen Kontext.

Dieser Abschnitt erläutert die folgenden Möglichkeiten zum Abrufen von Attributen:

Abrufen einer einzelnen Instanz eines Attributs

Im folgenden Beispiel wird die (im vorherigen Abschnitt beschriebene) DeveloperAttribute-Klasse auf die MainApp-Klasse auf Klassenebene angewendet. Die GetAttribute-Methode verwendet GetCustomAttribute, um die in DeveloperAttribute gespeicherten Werte auf Klassenebene abzurufen, bevor sie in der Konsole angezeigt werden.

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);
        }
    }
};
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);
        }
    }
}
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

Die Ausführung des vorherigen Programms zeigt den folgenden Text an:

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

Wenn das Attribut nicht gefunden wird, initialisiert die GetCustomAttribute-Methode MyAttribute auf einen Nullwert. In diesem Beispiel wird MyAttribute auf eine solche Instanz geprüft und der Benutzer benachrichtigt, wenn das Attribut nicht gefunden wird. Wenn das DeveloperAttribute nicht im Klassenbereich gefunden werden, zeigt die Konsole folgende Meldung an:

The attribute was not found.

Im vorangegangenen Beispiel wird davon ausgegangen, dass sich die Attributdefinition im aktuellen Namespace befindet. Denken Sie daran, den Namespace zu importieren, in dem sich die Attributdefinition befindet, wenn diese nicht im aktuellen Namespace ist.

Abrufen mehrerer Instanzen eines Attributs in demselben Gültigkeitsbereich angewendet

Im vorherigen Beispiel werden die zu prüfende Klasse und das zu suchende spezifische Attribut an die GetCustomAttribute-Methode übergeben. Dieser Code funktioniert gut, wenn nur eine Instanz eines Attributs auf Klassenebene angewendet wird. Wenn jedoch mehrere Instanzen eines Attributs auf derselben Klassenebene angewendet werden, ruft die GetCustomAttribute-Methode nicht alle Informationen ab. In Fällen, in denen mehrere Instanzen des gleichen Attributs im selben Gültigkeitsbereich angewendet werden, können Sie mithilfe der Attribute.GetCustomAttributes-Methode alle Instanzen eines Attributs in einem Array platzieren. Wenn beispielsweise zwei Instanzen von DeveloperAttribute auf Klassenebene derselben Klasse angewendet werden, kann die GetAttribute-Methode zum Anzeigen der in beiden Attributen gefundenen Informationen geändert werden. Denken Sie daran, mehrere Attribute auf derselben Ebene anzuwenden. Das Attribut muss mit der AllowMultiple-Eigenschaft definiert werden, die in der AttributeUsageAttribute-Klasse auf true festgelegt ist.

Im folgenden Codebeispiel wird veranschaulicht, wie Sie mit der GetCustomAttributes-Methode ein Array erstellen, das auf alle Instanzen von DeveloperAttribute in einer bestimmten Klasse verweist. Der Code gibt dann die Werte aller Attribute an die Konsole aus.

public:
    static void GetAttribute(Type^ t)
    {
        array<DeveloperAttribute^>^ MyAttributes =
            (array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);

        if (MyAttributes->Length == 0)
        {
            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)
{
    DeveloperAttribute[] MyAttributes =
        (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

    if (MyAttributes.Length == 0)
    {
        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 Shared Sub GetAttribute(t As Type)
    Dim MyAttributes() As DeveloperAttribute =
        CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

    If MyAttributes.Length = 0 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

Wenn keine Attribute gefunden werden, gibt dieser Code eine Warnung an den Benutzer aus. Andernfalls werden die in beiden Instanzen von DeveloperAttribute enthaltenen Informationen angezeigt.

Abrufen mehrerer Instanzen eines Attributs auf unterschiedliche Bereiche angewendet

Die Methoden GetCustomAttributes und GetCustomAttribute durchsuchen nicht eine ganze Klasse, um Instanzen eines Attributs in dieser Klasse zurückzugeben. Stattdessen suchen sie nur nach einer bestimmten Methode oder einem bestimmten Element zu einem gegebenen Zeitpunkt. Angenommen, Sie haben eine Klasse, für die das gleiche Attribut auf jedes Element angewendet wurde. Um nun die Werte in den Attributen abzurufen, die auf diese Elemente angewendet wurden, müssen Sie jede Methode oder jedes Element einzeln für GetCustomAttributes und GetCustomAttribute bereitstellen.

Im folgenden Codebeispiel wird eine Klasse als Parameter akzeptiert und nach dem DeveloperAttribute (zuvor definiert) auf Klassenebene und in jeder einzelnen Methode dieser Klasse gesucht.

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);
            }
        }
    }
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 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

Wenn auf Methoden- oder Klassenebene keine Instanzen von DeveloperAttribute gefunden werden, benachrichtigt die GetAttribute-Methode den Benutzer, dass keine Attribute gefunden wurden, und zeigt den Namen der Methode oder Klasse an, die das Attribut nicht enthält. Wenn ein Attribut gefunden wird, zeigt die Konsole die Felder Name, Level und Reviewed an.

Sie können die Elemente der Type-Klasse verwenden, um die einzelnen Methoden und Elemente der übergebenen Klasse abzurufen. In diesem Beispiel wird zuerst das Type-Objekt abgefragt, um Attributinformationen für die Klassenebene abzurufen. Als Nächstes wird Type.GetMethods verwendet, um Instanzen aller Methoden in einem Array von System.Reflection.MemberInfo-Objekten zu platzieren, um Attributinformationen für die Methodenebene abzurufen. Sie können mithilfe der Type.GetProperties-Methode nach Attributen auf Eigenschaftenebene oder mithilfe von Type.GetConstructors nach Attributen auf Konstruktorebene suchen.

Siehe auch