Share via


擷取儲存於屬性中的資訊

更新:2007 年 11 月

擷取自訂屬性是一簡單的程序。首先,宣告您想要擷取的屬性的執行個體。接著,使用 Attribute.GetCustomAttribute 方法來初始化新屬性成您想要擷取的屬性值。一旦屬性初始化後,您只要使用它的屬性來取得值。

重要事項:

本主題將說明如何替載入至執行內容的程式碼擷取屬性。若要替載入至僅限反映之內容的程式碼擷取屬性,您必須使用 CustomAttributeData 類別,如 HOW TO:將組件載入僅限反映的內容所示。

這個章節描述下列擷取屬性的方式:

  • 擷取屬性的單一執行個體

  • 擷取套用至相同範圍的屬性的多個執行個體

  • 擷取套用至不同範圍的屬性的多個執行個體

擷取屬性的單一執行個體

下列範例中,DeveloperAttribute (前面章節描述的) 套用至在類別層級上的 MainApp 類別。GetAttribute 方法使用 GetCustomAttribute,在顯示到主控台 (Console) 之前擷取儲存於類別層級上 DeveloperAttribute 的值。

using System;

[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(null == MyAttribute)
            {
                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

<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

這個程式在執行時顯示下列文字。

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

如果找不到屬性,GetCustomAttribute 方法初始化 MyAttribute 為 null 值。這範例對此類執行個體檢查 MyAttribute,並且如果找不到屬性將告知使用者。如果類別範圍中找不到 DeveloperAttribute,則將下列訊息顯示到主控台。

The attribute was not found. 

這範例假設屬性定義在目前命名空間中。如果它不是在目前的命名空間中,請記得將屬性定義所在的命名空間匯入。

擷取套用至相同範圍的屬性的多個執行個體

前面範例中,要檢查的類別和要尋找的特定屬性被傳遞到 GetCustomAttribute。如果類別層級上只套用一個屬性執行個體,那個程式碼將正常運作。然而,如果在相同類別層級套用屬性的多個執行個體,GetCustomAttribute 方法不會擷取所有資訊。假使相同屬性的多個執行個體套用到相同範圍,您可以使用 Attribute.GetCustomAttributes 將屬性的所有執行個體放到陣列裡。例如,如果 DeveloperAttribute 的兩個執行個體套用至相同類別的類別層級上,可以修改 GetAttribute 方法以顯示兩個屬性中都有的資訊。請記得,若要在相同層級套用多重屬性 (Attribute),必須在 AttributeUsageAttribute 中將 AllowMultiple 屬性 (Property) 設定為 true 以定義屬性 (Attribute)。

下列程式碼範例說明如何使用 GetCustomAttributes 方法來建立陣列,參考任何指定類別中 DeveloperAttribute 的所有執行個體。接著顯示所有屬性值到主控台。

public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttribute =
    (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));
    
    if(null == MyAttribute)
    {
        Console.WriteLine("The attribute was not found.");
    }
    else
    {
        for(int i = 0 ; i < MyAttribute.Length ; i++)
        {
            //Get the Name value.    
            Console.WriteLine("The Name Attribute is: {0}." , MyAttribute[i].Name);
            //Get the Level value.  
            Console.WriteLine("The Level Attribute is: {0}." , MyAttribute[i].Level);
            //Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute[i].Reviewed);
        }
    }
}
Public Shared Sub GetAttribute(t As Type)
    Dim MyAttribute As DeveloperAttribute() = _
    CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())
       
    If MyAttribute Is Nothing Then
        Console.WriteLine("The attribute was not found.")
    Else
        Dim i As Integer
        For i = 0 To MyAttribute.Length - 1
            'Get the Name value. 
            Console.WriteLine("The Name Attribute is: {0}.", MyAttribute(i).Name)
            'Get the Level value.   
            Console.WriteLine("The Level Attribute is: {0}.", MyAttribute(i).Level)
            'Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute(i).Reviewed)
        Next i
    End If
End Sub

如果找不到屬性,這個程式碼會警示使用者。否則,顯示 DeveloperAttribute 的兩個執行個體包含的全部資訊。

擷取套用至不同範圍的屬性的多個執行個體

GetCustomAttributesGetCustomAttribute 方法不會搜尋整個類別和傳回類別中屬性的所有執行個體。也就是,它們一次只搜尋一個方法或成員。如果您將帶著相同屬性的類別套用到每個成員,而且您想要擷取套用到那些成員的所有屬性中的值,您必須將每個方法或成員個別提供給 GetCustomAttributesGetCustomAttribute

下列程式碼範例將類別當做參數,並且在類別層級和該類別的每一個個別方法上搜尋 DeveloperAttribute (前面定義的)。

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(null == att)
    {
        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(null == att)
        {
            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 Then
        Console.WriteLine("No attribute in class {0}.", t.ToString())
        Console.WriteLine()
    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}.", att.Reviewed)
        Console.WriteLine()
    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.
    Dim i As Integer
    For i = 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}.", MyMemberInfo(i).ToString())
            Console.WriteLine()
        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}.", MyMemberInfo(i).ToString(), att.Reviewed)
            Console.WriteLine()
        End If
    Next i
End Sub

如果在方法層級或類別層級上找不到 DeveloperAttribute 的執行個體,GetAttribute 方法會告知使用者找不到屬性,並顯示不包含屬性的方法或類別。如果找到屬性,則將 Name、Level 和 Reviewed 欄位顯示到主控台。

您可以使用 Type 類別的成員,以取得傳遞的類別中的個別方法和成員。這範例首先查詢 Type 物件以取得類別層級的屬性資訊。其次,它使用 Type.GetMethods 將所有方法的執行個體放到 System.Reflection.MemberInfo 物件的陣列中,來擷取方法層級的屬性資訊。您也可以使用 Type.GetProperties 方法在屬性 (Property) 層級上檢查屬性 (Attribute),或 Type.GetConstructors 在建構函式層級上檢查屬性 (Attribute)。

請參閱

參考

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

其他資源

使用屬性擴充中繼資料