存取自定義屬性
建立屬性與程式項目的關聯之後,就可以使用反映來查詢其存在狀況和值。 .NET 提供 MetadataLoadContext,您可以使用它來檢查無法載入執行的程式代碼。
MetadataLoadContext
無法執行載入內容中的 MetadataLoadContext 程式代碼。 這表示無法建立自訂屬性的執行個體,因為這將需要執行其建構函式。 若要載入及檢查內容中的 MetadataLoadContext 自訂屬性,請使用 類別 CustomAttributeData 。 您可以使用靜態 CustomAttributeData.GetCustomAttributes 方法的適當多載,以取得此類別的執行個體。 如需詳細資訊,請參閱操作說明:使用 MetadataLoadContext 檢查組件內容。
執行內容
查詢執行內容中屬性的主要反映方法是 MemberInfo.GetCustomAttributes 和 Attribute.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(...)
{
}
}
如果運行時間嘗試擷取附加至 GetLanguage
方法之公用自定義屬性類型的DescriptionAttribute自定義屬性,它會執行下列動作:
- 運行時間會檢查的
Type.GetCustomAttributes(Type type)
型別自變數DescriptionAttribute
是否為公用,因此可見且可存取。 - 執行時間會檢查衍生自
DescriptionAttribute
的使用者定義型MyDescriptionAttribute
別在System.Web.dll元件中是可見且可存取的,其中附加至 方法GetLanguage()
。 - 運行時間會檢查 的建構函
MyDescriptionAttribute
式在System.Web.dll元件中是否可見且可存取。 - 運行時間會使用自定義屬性參數呼叫 的建構函
MyDescriptionAttribute
式,並將新的 物件傳回給呼叫端。
自訂屬性反映模型可能會流失在其中定義使用者定義型別之組件外部的類型執行個體。 這與運行時間系統連結庫中傳回使用者定義型別實例的成員不同,例如 Type.GetMethods 傳回 對象的數位 RuntimeMethodInfo
。 若要防止用戶端探索使用者定義自訂屬性類型的資訊,請將類型的成員定義為非公用。
下列範例示範如何使用反映來存取自訂屬性的基本方式。
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