存取自訂屬性
更新:2007 年 11 月
在屬性已經與程式項目關聯之後,反映可以用來查詢它們的存在和值。在 .NET Framework 1.0 和 1.1 版中,會在執行內容中檢查自訂屬性。.NET Framework 2.0 版提供了新的載入內容,這是僅限反映的內容,可用來檢查無法載入來執行的程式碼。
僅限反映的內容
載入到僅限反映的內容中之程式碼無法加以執行;這表示無法建立自訂屬性的執行個體,因為這將需要執行其建構函式。若要載入及檢查僅限反映的內容中的自訂屬性,請使用 CustomAttributeData 類別。您可以使用靜態 CustomAttributeData.GetCustomAttributes 方法的適當多載,藉以取得這個類別的執行個體。請參閱 HOW TO:將組件載入僅限反映的內容。
執行內容
查詢執行內容中的屬性之主要反映方法為 System.Reflection.MemberInfo.GetCustomAttributes 和 System.Reflection.Assembly.GetCustomAttributes。
自訂屬性的存取範圍針對它所附加的組件來檢查。這等於檢查自訂屬性所附加的組件型別中之方法,是否可以呼叫自訂屬性 (Attribute) 的建構函式。
類似 System.Reflection.Assembly.GetCustomAttributes(Type, Boolean) 的方法會檢查型別引數的可視性和存取範圍。只有包含使用者定義型別的組件中的程式碼可以使用 GetCustomAttributes 擷取該型別的自訂屬性。
下列 C# 範例是典型的自訂屬性設計模式。它說明 Runtime 自訂屬性反映模型。
System.DLL
public class DescriptionAttribute : Attribute
{
}
System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}
public class LocalizationExtenderProvider
{
[MyDescriptionAttribute(...)]
public CultureInfo GetLanguage(...)
{
}
}
如果 Runtime 嘗試擷取附加至 GetLanguage 方法之公用自訂屬性型別 DescriptionAttribute 的自訂屬性,它便會執行下列動作:
執行階段會檢查 Type.GetCustomAttributes (型別 type) 的型別引數 DescriptionAttribute 是否為公用;如果是公用,則為可見及可存取。
Runtime 會檢查從 DescriptionAttribute 衍生的使用者定義型別 MyDescriptionAttribute 在 System.Web.DLL 組件 (它是在這個組件中附加至 GetLanguage() 方法) 內是否為可見和可存取。
Runtime 會檢查 MyDescriptionAttribute 的建構函式在 System.Web.DLL 組件內是否為可見和可存取。
Runtime 會以自訂屬性參數呼叫 MyDescriptionAttribute 的建構函式,並將新物件傳回呼叫端。
自訂屬性反映模型可能會將使用者定義型別的執行個體遺漏在定義型別所在的組件之外。這無異於執行階段系統程式庫中會傳回使用者定義型別執行個體的成員,例如,傳回 RuntimeMethodInfo 物件陣列的 Type.GetMethods()。若要防止用戶端探索關於使用者定義自訂屬性型別的資訊,請將型別的成員定義為非公用。
下列範例示範使用反映存取自訂屬性的基本方式。
Class Class1
Public Shared Sub Main()
Dim info As System.Reflection.MemberInfo = GetType(Class1)
Dim attributes() As Object = info.GetCustomAttributes(True)
For i As Integer = 0 To attributes.Length - 1
System.Console.WriteLine(attributes(i))
Next i
End Sub
End Class
class MyClass
{
public static void Main()
{
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
System.Console.WriteLine(attributes[i]);
}
}
}