擷取儲存於屬性中的資訊Retrieving Information Stored in Attributes

擷取自訂屬性是一個簡單的程序。Retrieving a custom attribute is a simple process. 首先,對想要擷取的屬性宣告執行個體。First, declare an instance of the attribute you want to retrieve. 然後,使用 Attribute.GetCustomAttribute 方法將新屬性初始化為所要擷取之屬性的值。Then, use the Attribute.GetCustomAttribute method to initialize the new attribute to the value of the attribute you want to retrieve. 在將新屬性 (Attribute) 初始化之後,只要使用其屬性 (Poperty) 即可取得值。Once the new attribute is initialized, you simply use its properties to get the values.

重要

本文說明如何針對載入到執行內容的程式碼擷取屬性。This topic describes how to retrieve attributes for code loaded into the execution context. 若要對載入僅限反射內容中的程式碼擷取屬性,您必須使用 CustomAttributeData 類別,如以下連結所示:如何:將組件載入僅限反映的內容To retrieve attributes for code loaded into the reflection-only context, you must use the CustomAttributeData class, as shown in How to: Load Assemblies into the Reflection-Only Context.

本節說明下列擷取屬性的方式:This section describes the following ways to retrieve attributes:

擷取單一屬性執行個體Retrieving a Single Instance of an Attribute

在下列範例中,DeveloperAttribute (上節所述) 會在類別層級上套用至 MainApp 類別。In the following example, the DeveloperAttribute (described in the previous section) is applied to the MainApp class on the class level. GetAttribute 方法會先使用 GetCustomAttribute 來擷取類別層級上的 DeveloperAttribute 中所儲存的值,再顯示於主控台。The GetAttribute method uses GetCustomAttribute to retrieve the values stored in DeveloperAttribute on the class level before displaying them to the console.

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
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

此程式會在執行後顯示下列文字。This program displays the following text when executed.

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

如果找不到屬性,GetCustomAttribute方法會將 MyAttribute 初始化為 Null 值。If the attribute is not found, the GetCustomAttribute method initializes MyAttribute to a null value. 此範例會檢查 MyAttribute 是否有此類執行個體,並在找不到屬性時通知使用者。This example checks MyAttribute for such an instance and notifies the user if no attribute is found. 如果在類別範圍中找不到 DeveloperAttribute,會在主控台顯示下列訊息。If the DeveloperAttribute is not found in the class scope, the following message displays to the console.

The attribute was not found.   

此範例會假設屬性定義在目前的命名空間中。This example assumes that the attribute definition is in the current namespace. 如果屬性定義不在目前的命名空間中,請記得匯入屬性定義所在的命名空間。Remember to import the namespace in which the attribute definition resides if it is not in the current namespace.

擷取套用至相同範圍的多個屬性執行個體Retrieving Multiple Instances of an Attribute Applied to the Same Scope

在上述範例中,要檢查的類別和要尋找的特定屬性都會傳遞至 GetCustomAttributeIn the previous example, the class to inspect and the specific attribute to find are passed to GetCustomAttribute. 如果類別層級上只套用一個屬性執行個體,該程式碼可以運作良好。That code works well if only one instance of an attribute is applied on the class level. 不過,如果在相同的類別層級上套用多個屬性執行個體,GetCustomAttribute 方法不會擷取所有資訊。However, if multiple instances of an attribute are applied on the same class level, the GetCustomAttribute method does not retrieve all the information. 在相同屬性的多個執行個體都套用至相同範圍的情況下,您可以使用 Attribute.GetCustomAttributes 將屬性的所有執行個體放入陣列。In cases where multiple instances of the same attribute are applied to the same scope, you can use Attribute.GetCustomAttributes to place all instances of an attribute into an array. 例如,如果在相同類別的類別層級上套用 DeveloperAttribute 的兩個執行個體,可修改 GetAttribute 方法以顯示在兩個屬性中找到的資訊。For example, if two instances of DeveloperAttribute are applied on the class level of the same class, the GetAttribute method can be modified to display the information found in both attributes. 請記住,若要在相同層級上套用多個屬性,屬性必須使用 AttributeUsageAttribute 中設定為 trueAllowMultiple 屬性來定義。Remember, to apply multiple attributes on the same level, the attribute must be defined with the AllowMultiple property set to true in the AttributeUsageAttribute.

下列程式碼範例會示範如何使用 GetCustomAttributes 方法,來建立會參考任何指定類別中所有 DeveloperAttribute 執行個體的陣列。The following code example shows how to use the GetCustomAttributes method to create an array that references all instances of DeveloperAttribute in any given class. 所有屬性的值隨即顯示在主控台。The values of all attributes are then displayed to the console.

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

如果找不到任何屬性,此程式碼會警示使用者。If no attributes are found, this code alerts the user. 否則,DeveloperAttribute 的兩個執行個體中所包含的資訊隨即顯示。Otherwise, the information contained in both instances of DeveloperAttribute is displayed.

擷取套用至不同範圍的多個屬性執行個體Retrieving Multiple Instances of an Attribute Applied to Different Scopes

GetCustomAttributesGetCustomAttribute 方法不會搜尋整個類別,然後傳回該類別中屬性的所有執行個體。The GetCustomAttributes and GetCustomAttribute methods do not search an entire class and return all instances of an attribute in that class. 而會一次只搜尋一個指定的方法或成員。Rather, they search only one specified method or member at a time. 如果您有每個成員都套用相同屬性的類別,並想要擷取所有套用至那些成員的屬性值,就必須將每個方法或成員個別提供給 GetCustomAttributesGetCustomAttributeIf you have a class with the same attribute applied to every member and you want to retrieve the values in all the attributes applied to those members, you must supply every method or member individually to GetCustomAttributes and GetCustomAttribute.

下列程式碼範例會將類別視為參數,並在類別層級和該類別的每一個方法搜尋 DeveloperAttribute (先前所定義)。The following code example takes a class as a parameter and searches for the DeveloperAttribute (defined previously) on the class level and on every individual method of that class.

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

如果在方法層級或類別層級上找不到任何 DeveloperAttribute 的執行個體,GetAttribute 會通知使用者找不到任何屬性,並顯示不包含該屬性的方法或類別名稱。If no instances of the DeveloperAttribute are found on the method level or class level, the GetAttribute method notifies the user that no attributes were found and displays the name of the method or class that does not contain the attribute. 如果找到屬性,會在主控台顯示 NameLevelReviewed 欄位。If an attribute is found, the Name, Level, and Reviewed fields are displayed to the console.

您可以使用 Type 類別的成員來取得所傳遞類別中的個別方法和成員。You can use the members of the Type class to get the individual methods and members in the passed class. 此範例會先查詢 Type 物件以取得類別層級的屬性資訊。This example first queries the Type object to get attribute information for the class level. 接著,它會使用 Type.GetMethods 以將所有方法的執行個體置入 System.Reflection.MemberInfo 物件的陣列,以擷取方法層級的屬性資訊。Next, it uses Type.GetMethods to place instances of all methods into an array of System.Reflection.MemberInfo objects to retrieve attribute information for the method level. 您也可以使用 Type.GetProperties 方法來檢查屬性層級上的屬性,或使用 Type.GetConstructors 來檢查建構函式層級上的屬性。You can also use the Type.GetProperties method to check for attributes on the property level or Type.GetConstructors to check for attributes on the constructor level.

另請參閱See also