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

C# Attribute(屬性)核心機制與自訂應用實戰

     編輯:關於C#

什麼是 Attribute?

Attribute(屬性)是附加在程式碼元素(類別、方法、屬性、欄位、事件等)上的宣告式中繼資料。本質上是一個繼承自 System.Attribute 的類別實例,編譯時嵌入組件中繼資料,執行期可透過反射讀取。

內建 Attribute 實例:DefaultEvent

控制項雙擊時自動導向的預設事件即由 [DefaultEvent("EventName")] 決定。

[DefaultEvent("FormClosed")]
public partial class Form1 : Form { ... }

public partial class Form2 : Form1 { ... }
// 設計器雙擊 Form2 時,直接跳至 FormClosed 事件而非 Load 事件

Attribute 的核心特性

  • 非關鍵字:中括號語法實為建構函式呼叫,如 [Obsolete("msg")] 等同 new ObsoleteAttribute("msg")。
  • 可套用目標:[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 控制可標註位置。
  • 執行期可讀:透過 MemberInfo.GetCustomAttributes() 取得實例。
  • 可攜帶參數:建構函式參數可為常數、Type、陣列等。

自訂 Attribute 完整範例

using System;
using System.Reflection;

namespace ConsoleApplication11
{
    // 1. 定義屬性類別
    public class Test1Attribute : Attribute
    {
        public string Description { get; }
        public Test1Attribute() { Description = ""; }
        public Test1Attribute(string desc) { Description = desc; }
        public override string ToString() => Description;
    }

    public class Test2Attribute : Attribute
    {
        public int Value { get; }
        public Test2Attribute(int v) { Value = v; }
        public override string ToString() => Value.ToString();
    }

    // 2. 套用屬性
    [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;
    }

    // 3. 反射讀取
    class Program
    {
        static void Main()
        {
            Type t = typeof(TestClass);

            Console.WriteLine("=== 類別屬性 ===");
            foreach (var attr in t.GetCustomAttributes(false))
                Console.WriteLine($"{attr.GetType().Name}: {attr}");

            Console.WriteLine("\n=== 欄位屬性 ===");
            foreach (var attr in t.GetField("_aa").GetCustomAttributes(typeof(Test1Attribute), true))
                Console.WriteLine($"{attr.GetType().Name}: {attr}");

            Console.WriteLine("\n=== 屬性屬性 ===");
            foreach (var attr in t.GetProperty("aa").GetCustomAttributes(typeof(Test1Attribute), true))
                Console.WriteLine($"{attr.GetType().Name}: {attr}");

            Console.WriteLine("\n=== 方法屬性 ===");
            foreach (var attr in t.GetMethod("test").GetCustomAttributes(typeof(Test1Attribute), true))
                Console.WriteLine($"{attr.GetType().Name}: {attr}");

            Console.WriteLine("\n=== 事件屬性 ===");
            foreach (var attr in t.GetEvent("onTest").GetCustomAttributes(typeof(Test1Attribute), true))
                Console.WriteLine($"{attr.GetType().Name}: {attr}");

            Console.Read();
        }
    }
}

實務應用場景

  • 資料驗證:[Required], [StringLength(50)] → MVC/WebAPI 模型綁定自動驗證。
  • 序列化控制:[JsonIgnore], [XmlElement("Name")]。
  • 單元測試:[TestMethod], [DataRow(1,2)]。
  • DI 容器:[Inject], [Service]。
  • 程式碼產生/編譯時檢查:Roslyn Analyzer 讀取 Attribute 產生警告/錯誤。

結語

Attribute 是「程式碼註釋程式碼」的強大機制。善用內建與自訂 Attribute,配合反射或原始碼分析,能構建聲明式、可擴充的框架架構,大幅減少樣板程式碼。

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