Freigeben über


Abrufen von informationen, die in Attributen gespeichert sind

Das Abrufen eines benutzerdefinierten Attributs ist ein einfacher Prozess. Deklarieren Sie zunächst eine Instanz des Attributs, das Sie abrufen möchten. Verwenden Sie dann die Attribute.GetCustomAttribute-Methode, um das neue Attribut auf den Wert des Attributs zu initialisieren, das Sie abrufen möchten. Nachdem 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 wurde. Zum Abrufen von Attributen für Code, der in den Nur-Reflexionskontext geladen wurde, müssen Sie die CustomAttributeData Klasse verwenden, wie unter So geht's: Assemblies in den Reflection-Only-Kontext laden beschrieben.

In diesem Abschnitt werden die folgenden Methoden zum Abrufen von Attributen beschrieben:

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 auf Klassenebene gespeicherten Werte abzurufen, bevor sie in der Konsole angezeigt werden.

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: {MyAttribute.Name}.");
            // Get the Level value.
            Console.WriteLine($"The Level Attribute is: {MyAttribute.Level}.");
            // Get the Reviewed value.
            Console.WriteLine($"The Reviewed Attribute is: {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 in einen Nullwert. In diesem Beispiel wird MyAttribute für eine solche Instanz überprüft und der Benutzer benachrichtigt, wenn das Attribut nicht gefunden wird. Wenn DeveloperAttribute im Klassenbereich nicht gefunden wird, zeigt die Konsole die folgende Meldung an:

The attribute was not found.

Im vorherigen 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 sie nicht im aktuellen Namespace enthalten ist.

Abrufen mehrerer Instanzen eines Attributs, das auf denselben Bereich angewendet wird

Im vorherigen Beispiel werden die zu prüfende Klasse und das spezifische Attribut, das gesucht werden soll, 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 desselben Attributs auf denselben Bereich angewendet werden, können Sie Attribute.GetCustomAttributes Methode verwenden, um alle Instanzen eines Attributs in ein Array zu platzieren. Wenn beispielsweise zwei Instanzen von DeveloperAttribute auf die Klassenebene derselben Klasse angewendet werden, kann die GetAttribute-Methode geändert werden, um die informationen anzuzeigen, die in beiden Attributen gefunden wurden. Denken Sie daran, mehrere Attribute auf derselben Ebene anzuwenden. Das Attribut muss mit der AllowMultiple-Eigenschaft definiert werden, die in der true Klasse auf AttributeUsageAttribute festgelegt ist.

Im folgenden Codebeispiel wird gezeigt, 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 in der Konsole aus.

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: {MyAttributes[i].Name}.");
            // Get the Level value.
            Console.WriteLine($"The Level Attribute is: {MyAttributes[i].Level}.");
            // Get the Reviewed value.
            Console.WriteLine($"The Reviewed Attribute is: {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, warnt dieser Code den Benutzer. Andernfalls werden die in beiden Instanzen von DeveloperAttribute enthaltenen Informationen angezeigt.

Abrufen mehrerer Instanzen eines Attributs, das auf verschiedene Bereiche angewendet wird

Die Methoden GetCustomAttributes und GetCustomAttribute durchsuchen keine gesamte Klasse und geben alle Instanzen eines Attributs in dieser Klasse zurück. Stattdessen durchsuchen sie jeweils nur eine angegebene Methode oder ein bestimmtes Element. Wenn Sie eine Klasse mit demselben Attribut auf jedes Element angewendet haben und die Werte in allen Attributen abrufen möchten, die auf diese Member angewendet werden, müssen Sie jede Methode oder jedes Element einzeln für GetCustomAttributes und GetCustomAttributeangeben.

Im folgenden Codebeispiel wird eine Klasse als Parameter verwendet und nach dem DeveloperAttribute (zuvor definiert) auf Klassenebene und auf 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, typeof (DeveloperAttribute));

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

    // 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 {MyMemberInfo[i].ToString()}.\n");
        }
        else
        {
            Console.WriteLine($"The Name Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Name}.");
            Console.WriteLine($"The Level Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Level}.");
            Console.WriteLine($"The Reviewed Attribute for the {MyMemberInfo[i].ToString()} member is: {att.Reviewed}.\n");
        }
    }
}
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 keine Instanzen der DeveloperAttribute auf Methodenebene oder Klassenebene 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, Levelund 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 zunächst das Type-Objekt abgerufen, um Attributinformationen für die Klassenebene abzurufen. Als Nächstes wird Type.GetMethods verwendet, um Instanzen aller Methoden in ein Array von System.Reflection.MemberInfo Objekten zu platzieren, um Attributinformationen für die Methodenebene abzurufen. Sie können auch die Type.GetProperties-Methode verwenden, um nach Attributen auf Eigenschaftsebene zu suchen, oder Type.GetConstructors, um auf Attribute auf Konstruktorebene zu überprüfen.

Abrufen von Attributen aus Klassenmitgliedern

Zusätzlich zum Abrufen von Attributen auf Klassenebene können Attribute auch auf einzelne Member wie Methoden, Eigenschaften und Felder angewendet werden. Die Methoden GetCustomAttribute und GetCustomAttributes können zum Abrufen dieser Attribute verwendet werden.

Beispiel

Das folgende Beispiel veranschaulicht das Abrufen eines Attributs, das auf eine Methode angewendet wird:

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    public string Description { get; }
    public MyAttribute(string description) { Description = description; }
}

public class MyClass
{
    [MyAttribute("This is a sample method.")]
    public void MyMethod() { }
}

class AttributeRetrieval
{
    public static void Main()
    {
        // Create an instance of MyClass
        MyClass myClass = new MyClass();

        // Retrieve the method information for MyMethod
        MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod");
        MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute));

        if (attribute != null)
        {
            // Print the description of the method attribute
            Console.WriteLine($"Method Attribute: {attribute.Description}");
        }
        else
        {
            Console.WriteLine("Attribute not found.");
        }
    }
}

Siehe auch