首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 屬性類別的實作與反射應用(二)

     編輯:關於C語言

在 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();
}

實務應用場景

  • 框架開發:ASP.NET Core 的 [HttpGet]、[Authorize] 等皆為屬性,路由與授權邏輯即在執行期透過反射解析。
  • 序列化控制:[JsonIgnore]、[XmlElement] 指導序列化器處理欄位/屬性。
  • 單元測試:[Test]、[TestCase] 標記測試方法,測試執行器透過反射發現並執行。
  • 程式碼分析/原始碼產生器:Roslyn 分析器可讀取屬性以實作自訂診斷或產生程式碼。

注意事項

  1. AttributeTargets:可用 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] 限制屬性可套用的目標與是否允許重複。
  2. 效能:反射有一定開銷,高頻呼叫處建議快取 MemberInfo 或屬性實例。
  3. 繼承:GetCustomAttributes(true) 的第二個參數控制是否搜尋繼承鏈。

掌握屬性類別的定義與反射讀取,能讓你設計出更具擴充性、可配置的 C# 程式庫與應用程式架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved