——解鎖元數據標記的高級玩法
💡 核心認知:特性本質揭秘
public sealed class ReviewCommentAttribute : System.Attribute { ... }
- 特性即特殊類:所有自定義特性必須繼承
System.Attribute
(基礎規則) - 命名規范:類名需以
Attribute
后綴結尾(如MyAttributeAttribute
) - 密封建議:強烈推薦聲明為
sealed
類(防止意外繼承)
?? 特性構造三部曲
1?? 構造函數設計原則
public MyAttributeAttribute(string desc, string ver)
{Description = desc; // 位置參數 VersionNumber = ver;
}
- 強制公有構造:至少需一個公共構造函數(隱式無參構造也可用)
- 參數限制:僅接受編譯期常量(常量表達式)
2?? 應用時的構造規則
[MyAttribute("Holds a value")] // 單參數構造
[MyAttribute("V1.3", Reviewer="Alice")] // 位置參數+命名參數
- 位置參數優先:對應構造函數參數順序
- 命名參數擴展:初始化公共字段/屬性(需在位置參數后)
3?? 無參構造的簡寫
[MyAttr] // 等效于 [MyAttr()]
class MyClass
🔐 精準控制特性作用域(AttributeUsage)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, // 目標類型 Inherited = false, // 禁止繼承 AllowMultiple = false // 禁止重復應用
)]
public sealed class AuditAttribute : Attribute { ... }
參數 | 作用 | 默認值 |
---|---|---|
ValidOn | 指定目標類型(枚舉按位組合) | 必填 |
Inherited | 是否被派生類繼承 | true |
AllowMultiple | 同一目標是否允許多次應用 | false |
常用目標類型(AttributeTargets枚舉):
Class
|Method
|Property
Field
|Constructor
|Assembly
? 自定義特性最佳實踐
1. 職責單一
特性類應僅描述目標結構的元數據狀態(如版本/作者/描述)
2. 安全封裝
// ? 正確示范
public string Version { get; } // 只讀屬性// ? 避免
public void Validate() { ... } // 禁止添加方法
3. 參數設計規范
- 必需參數 → 通過構造函數位置參數傳遞
- 可選參數 → 通過公共字段/屬性+命名參數設置
4. 完整聲明示例
[AttributeUsage(AttributeTargets.Class)]
public sealed class ApiVersionAttribute : Attribute
{public string Version { get; }public string Author { get; set; } // 可選命名參數public ApiVersionAttribute(string version) => Version = version;
}// 應用示例
[ApiVersion("2.1.0", Author = "Jane")]
public class PaymentService { ... }
💎 關鍵要點回顧
概念 | 要點說明 |
---|---|
特性本質 | 繼承System.Attribute 的特殊類 |
構造函數 | 支持重載,參數需為編譯期常量 |
參數傳遞 | 位置參數必填在前,命名參數補充在后 |
作用域控制 | 用AttributeUsage 精確限制目標類型 |
安全實踐 | 密封類 + 只包含字段/屬性 + 顯式目標聲明 |
特性如代碼的“智能標簽”
它不改變邏輯,卻為程序注入結構化元數據。掌握自定義特性,等于擁有為代碼打上語義化標記的能力,讓架構意圖更清晰,讓擴展更優雅。