Pobieranie informacji przechowywanych w atrybutach

Pobieranie atrybutu niestandardowego jest prostym procesem. Najpierw zadeklaruj wystąpienie atrybutu, który chcesz pobrać. Następnie użyj metody , aby zainicjować nowy atrybut na wartość Attribute.GetCustomAttribute atrybutu, który chcesz pobrać. Po zainicjowania nowego atrybutu wystarczy użyć jego właściwości, aby uzyskać wartości.

Ważne

W tym temacie opisano sposób pobierania atrybutów dla kodu załadowanego do kontekstu wykonywania. Aby pobrać atrybuty dla kodu załadowanego do kontekstu tylko odbicia, należy użyć klasy , jak pokazano w tece CustomAttributeData How to: Load Assemblies into the Reflection-Only Context(Jak załadować zestawy do Reflection-Only kontekstu ).

W tej sekcji opisano następujące sposoby pobierania atrybutów:

Pobieranie pojedynczego wystąpienia atrybutu

W poniższym przykładzie klasa (opisana w poprzedniej sekcji) jest stosowana do DeveloperAttribute MainApp klasy na poziomie klasy. Metoda GetAttribute używa getCustomAttribute, aby pobrać wartości przechowywane na poziomie klasy przed DeveloperAttribute wyświetleniem ich w konsoli.

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

Ten program wyświetla następujący tekst po wykonaniu.

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

Jeśli atrybut nie zostanie znaleziony, metoda GetCustomAttribute inicjuje MyAttribute wartość null. W tym MyAttribute przykładzie sprawdza takie wystąpienie i powiadamia użytkownika, jeśli nie znaleziono atrybutu. Jeśli klasa DeveloperAttribute nie zostanie znaleziona w zakresie klasy, w konsoli zostanie wyświetlony następujący komunikat.

The attribute was not found.

W tym przykładzie przyjęto założenie, że definicja atrybutu znajduje się w bieżącej przestrzeni nazw. Pamiętaj, aby zaimportować przestrzeń nazw, w której znajduje się definicja atrybutu, jeśli nie znajduje się ona w bieżącej przestrzeni nazw.

Pobieranie wielu wystąpień atrybutu zastosowanego do tego samego zakresu

W poprzednim przykładzie klasa do sprawdzenia i określony atrybut do znalezienia są przekazywane do GetCustomAttribute klasy . Ten kod działa dobrze, jeśli na poziomie klasy jest stosowane tylko jedno wystąpienie atrybutu. Jeśli jednak wiele wystąpień atrybutu zostanie zastosowanych na tym samym poziomie klasy, metoda GetCustomAttribute nie pobierze wszystkich informacji. W przypadkach, gdy wiele wystąpień tego samego atrybutu jest stosowanych do tego samego zakresu, można użyć funkcji , aby umieścić wszystkie wystąpienia atrybutu Attribute.GetCustomAttributes w tablicy. Jeśli na przykład dwa wystąpienia klasy są stosowane na poziomie klasy tej samej klasy, można zmodyfikować metodę w celu wyświetlenia informacji znalezionych DeveloperAttribute GetAttribute w obu atrybutach. Pamiętaj, że aby zastosować wiele atrybutów na tym samym poziomie, atrybut musi być zdefiniowany za pomocą właściwości AllowMultiple ustawionej na wartość true w obiekcie AttributeUsageAttribute .

Poniższy przykład kodu pokazuje, jak za pomocą metody GetCustomAttributes utworzyć tablicę, która odwołuje się do wszystkich wystąpień w DeveloperAttribute dowolnej klasie. Wartości wszystkich atrybutów są następnie wyświetlane w konsoli.

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

Jeśli nie zostaną znalezione żadne atrybuty, ten kod powiadamia użytkownika. W przeciwnym razie zostaną wyświetlone informacje zawarte w obu DeveloperAttribute wystąpieniach klasy .

Pobieranie wielu wystąpień atrybutu zastosowanego do różnych zakresów

Metody GetCustomAttributes i GetCustomAttribute nie wyszukuje całej klasy i nie zwracają wszystkich wystąpień atrybutu w tej klasie. Zamiast tego przeszukują tylko jedną określoną metodę lub członka jednocześnie. Jeśli masz klasę z tym samym atrybutem zastosowanym do każdego członka i chcesz pobrać wartości we wszystkich atrybutach zastosowanych do tych składowych, musisz podać każdą metodę lub składową indywidualnie do właściwości GetCustomAttributes i GetCustomAttribute.

Poniższy przykład kodu przyjmuje klasę jako parametr i wyszukuje (zdefiniowane wcześniej) na poziomie klasy i na każdej indywidualnej DeveloperAttribute metodzie tej klasy.

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

Jeśli nie znaleziono żadnych wystąpień klasy na poziomie metody lub klasy, metoda powiadamia użytkownika, że nie znaleziono żadnych atrybutów, i wyświetla nazwę metody lub klasy, która nie zawiera DeveloperAttribute GetAttribute atrybutu. Jeśli atrybut zostanie znaleziony, Name pola , i zostaną wyświetlone w Level Reviewed konsoli.

Możesz użyć składowych klasy , aby uzyskać poszczególne metody i składowe Type w przekazanej klasie. W tym przykładzie najpierw wysyła kwerendę do obiektu Type, aby uzyskać informacje o atrybutach dla poziomu klasy. Następnie używa metody , aby umieścić wystąpienia wszystkich metod w tablicy obiektów w celu pobrania informacji Type.GetMethods System.Reflection.MemberInfo o atrybutach dla poziomu metody. Możesz również użyć metody , aby sprawdzić atrybuty na poziomie właściwości lub sprawdzić atrybuty Type.GetProperties Type.GetConstructors na poziomie konstruktora.

Zobacz też