在 C# 中,屬性類別提供了一種將中繼資料附加至程式碼元素(類別、方法、屬性、欄位、事件等)的強大機制。透過繼承 System.Attribute,開發人員可自訂屬性,並在執行期利用反射讀取這些資訊,進而實現靈活的框架設計、配置驅動邏輯或程式碼分析工具。
自訂屬性類別需繼承 System.Attribute,並可定義建構函式與屬性來儲存資料。以下範例展示兩個簡單的屬性類別 Test1(接受字串參數)與 Test2(接受整數參數),並覆寫 ToString() 以便輸出:
public class Test1 : System.Attribute
{
private string _strName = "";
public Test1() { }
public Test1(string str) { _strName = str; }
public override string ToString() => _strName;
}
public class Test2 : Attribute
{
private int _value;
public Test2(int v) { _value = v; }
public override string ToString() => _value.ToString();
}
使用方括號語法即可在編譯期將屬性「貼」到目標元素上。實際上這相當於呼叫屬性類別的建構函式。以下程式碼分別在類別、欄位、屬性、方法與事件上套用 Test1 與 Test2:
[Test1("jinjazz for TestClass")]
[Test2(12356)]
public class TestClass
{
[Test1("jinjazz for _aa欄位")]
public string _aa = "";
[Test1("jinjazz for aa 屬性")]
public string aa { get { return _aa; } }
[Test1("jinjazz for test 方法")]
public void test() { }
[Test1("jinjazz for onTest 事件")]
public event EventHandler onTest;
}
在執行期,可使用 Type.GetCustomAttributes()、FieldInfo.GetCustomAttributes()、PropertyInfo.GetCustomAttributes()、MethodInfo.GetCustomAttributes()、EventInfo.GetCustomAttributes() 等方法取得屬性實例。以下主程式示範如何逐一檢索並列印:
static void Main()
{
// 取得類別層級屬性
foreach (var obj in typeof(TestClass).GetCustomAttributes(false))
Console.WriteLine($"{obj.GetType().Name}: {obj}");
// 取得欄位屬性
foreach (var obj in typeof(TestClass).GetField("_aa").GetCustomAttributes(typeof(Test1), true))
Console.WriteLine($"{obj.GetType().Name}: {obj}");
// 取得屬性屬性
foreach (var obj in typeof(TestClass).GetProperty("aa").GetCustomAttributes(typeof(Test1), true))
Console.WriteLine($"{obj.GetType().Name}: {obj}");
// 取得方法屬性
foreach (var obj in typeof(TestClass).GetMethod("test").GetCustomAttributes(typeof(Test1), true))
Console.WriteLine($"{obj.GetType().Name}: {obj}");
// 取得事件屬性
foreach (var obj in typeof(TestClass).GetEvent("onTest").GetCustomAttributes(typeof(Test1), true))
Console.WriteLine($"{obj.GetType().Name}: {obj}");
Console.Read();
}
[HttpGet]、[Authorize] 等皆為屬性,路由與授權邏輯即在執行期透過反射解析。[JsonIgnore]、[XmlElement] 指導序列化器處理欄位/屬性。[Test]、[TestCase] 標記測試方法,測試執行器透過反射發現並執行。[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] 限制屬性可套用的目標與是否允許重複。MemberInfo 或屬性實例。GetCustomAttributes(true) 的第二個參數控制是否搜尋繼承鏈。掌握屬性類別的定義與反射讀取,能讓你設計出更具擴充性、可配置的 C# 程式庫與應用程式架構。