存取自訂屬性

建立屬性與程式項目的關聯之後,就可以使用反映來查詢其存在狀況和值。 在 .NET Framework 1.0 和 1.1 版中,會檢查執行內容中的自訂屬性。 .NET Framework 2.0 版提供新的載入內容,就是僅限反映的內容,這可以用來檢查無法載入來執行的程式碼。

僅限反映的內容

無法執行載入僅限反映內容的程式碼。 這表示無法建立自訂屬性的執行個體,因為這將需要執行其建構函式。 若要載入和檢查僅限反映內容中的自訂屬性,請使用 CustomAttributeData 類別。 您可以使用靜態 CustomAttributeData.GetCustomAttributes 方法的適當多載,以取得此類別的執行個體。 請參閱如何:將組件載入僅限反映的內容

執行內容

查詢執行內容中屬性的主要反映方法是 MemberInfo.GetCustomAttributesAttribute.GetCustomAttributes

會檢查自訂屬性有關附加組件的存取性。 這相當於檢查附加自訂屬性中組件內之類型的方法是否可以呼叫自訂屬性的建構函式。

Assembly.GetCustomAttributes(Boolean) 這類方法會檢查型別引數的可視性和存取性。 只有包含使用者定義型別之組件中的程式碼才能使用 GetCustomAttributes 擷取類型的自訂屬性。

下列 C# 範例是典型自訂屬性設計模式。 它會說明執行階段自訂屬性反映模型。

System.DLL  
public class DescriptionAttribute : Attribute  
{  
}  
  
System.Web.DLL  
internal class MyDescriptionAttribute : DescriptionAttribute  
{  
}  
  
public class LocalizationExtenderProvider  
{  
    [MyDescriptionAttribute(...)]  
    public CultureInfo GetLanguage(...)  
    {  
    }  
}  

如果執行階段嘗試擷取附加至 DescriptionAttribute 方法之公開自訂屬性類型 DescriptionAttribute 的自訂屬性,則會執行下列動作:

  1. 執行階段會檢查 Type.GetCustomAttributes 的型別引數 DescriptionAttribute (鍵入 type) 是公用的,因此可見且可供存取。

  2. 執行階段會檢查衍生自 DescriptionAttribute 的使用者定義型別 MyDescriptionAttribute 是否可以在 System.Web.DLL 組件內顯示和存取,其中,它會附加至 GetLanguage() 方法。

  3. 執行階段會檢查 System.Web.DLL 組件內 MyDescriptionAttribute 的建構函式可見且可供存取。

  4. 執行階段會使用自訂屬性參數來呼叫 MyDescriptionAttribute 的建構函式,並將新物件傳回給呼叫者。

自訂屬性反映模型可能會流失在其中定義使用者定義型別之組件外部的類型執行個體。 這與傳回使用者定義型別執行個體的執行階段系統程式庫成員沒有差異,例如 Type.GetMethods 傳回 Type.GetMethods 物件的陣列。 若要防止用戶端探索使用者定義自訂屬性類型的資訊,請將類型的成員定義為非公用。

下列範例示範如何使用反映來存取自訂屬性的基本方式。

using namespace System;

public ref class ExampleAttribute : Attribute
{
private:
    String^ stringVal;

public:
    ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }


    property String^ StringValue
    {
        String^ get() { return stringVal; }
        void set(String^ value) { stringVal = value; }
    }
};

[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
    static void Main()
    {
        System::Reflection::MemberInfo^ info = Type::GetType("Class1");
        for each (Object^ attrib in info->GetCustomAttributes(true))
        {
            Console::WriteLine(attrib);
        }
    }
};

int main()
{
    Class1::Main();
}
using System;

public class ExampleAttribute : Attribute
{
    private string stringVal;

    public ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }

    public string StringValue
    {
        get { return stringVal; }
        set { stringVal = value; }
    }
}

[Example(StringValue="This is a string.")]
class Class1
{
    public static void Main()
    {
        System.Reflection.MemberInfo info = typeof(Class1);
        foreach (object attrib in info.GetCustomAttributes(true))
        {
            Console.WriteLine(attrib);
        }
    }
}
Public Class ExampleAttribute
    Inherits Attribute

    Private stringVal As String

    Public Sub New()
        stringVal = "This is the default string."
    End Sub

    Public Property StringValue() As String
        Get
            Return stringVal
        End Get
        Set(Value As String)
            stringVal = Value
        End Set
    End Property
End Class

<Example(StringValue:="This is a string.")> _
Class Class1
    Public Shared Sub Main()
        Dim info As System.Reflection.MemberInfo = GetType(Class1)
        For Each attrib As Object In info.GetCustomAttributes(true)
            Console.WriteLine(attrib)
        Next attrib
    End Sub
End Class

另請參閱