自定義屬性採用宣告式程式設計方式(HTML 也是此類)。它將額外資訊與目標元素關聯,編譯器在託管模組的中繼資料中產生額外資訊。所有符合 CLS 的屬性均衍生自 System.Attribute。
屬性分為定位參數(必須指定)和命名參數(可選)。可將多個屬性套用至單一目標,以逗號分隔。
標準寫法:
[AttributeUsage(AttributeTargets.Enum, Inherited = true, AllowMultiple = false)]
public class FlagAttribute : System.Attribute {
public FlagAttribute() { }
}
注意事項:
[Flag](去除 Attribute 後綴)。AttributeTargets 列舉限定適用範圍;AttributeTargets.All 表示適用於所有類型。AllowMultiple 指出是否可多次套用。大多數屬性僅能使用一次;少數如 ConditionalAttribute 需多次套用。Inherited 指出屬性是否可由衍生類別與覆寫成員繼承。僅 class/method/property/field/event/方法回傳值/方法參數支援繼承。Inherited 不會為衍生類別產生額外中繼資料,不影響行為,僅在組件中產生額外中繼資料。未設定 AttributeUsage 時,預設為 [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]。
不可為靜態;必須限制在盡可能小的類型範圍。盡量避免陣列參數(非零基陣列不符合 CLS)。屬性中定義 Type 類型時使用 typeof() 傳遞;定義 Object 類型可傳遞常數運算式(含 null),值類型執行時會裝箱。
使用 Type.IsDefined 檢查類型上的屬性(不建構實例,效率高)。使用 Attribute.GetCustomAttributes 取得套用於目標的屬性陣列。使用 Attribute.GetCustomAttribute 取得指定屬性類別的單一實例。
自定義屬性需覆寫 Match() 方法才能比較兩個實例,否則呼叫基類 Equals。範例展示了 Match 覆寫與 GetCustomAttribute 用法。
使用 System.Reflection.CustomAttributeData 類別及其靜態 GetCustomAttributes 方法,搭配 Assembly.ReflectionOnlyLoad() 取得組件進行分析。CustomAttributeData 提供 Constructor、ConstructorArguments、NamedArguments 三個唯讀屬性。
使用 System.Diagnostics.ConditionalAttribute 標記的屬性類別。#define 指令需置於 using 之前,決定該屬性是否會在 IL 中產生。