首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 要用巨集實現反射?別再造輪子了,.NET 內建反射機制才是正解

     編輯:程式設計綜合問答

問題:想用 C# 巨集模擬反射,把類別描述、屬性中繼資料、介面對應函式全包進去

提問者希望設計一個「巨集」,能將已定義類別的描述資訊(屬性讀寫類型、單位、閾值等)、以及指定 init、run、finalise 介面對應的具體函式,透過這個巨集來實現一套反射機制。

直接回答:C# 沒有巨集,也根本不需要

C# 本身就有完整、強大的內建反射機制(System.Reflection 命名空間),能在執行時動態:

  • 取得型別資訊:typeof(MyClass)、obj.GetType()
  • 列舉屬性/欄位/方法:GetProperties()、GetFields()、GetMethods()
  • 讀寫屬性值:prop.GetValue(obj)、prop.SetValue(obj, val)
  • 動態呼叫方法:method.Invoke(obj, args)
  • 取得自訂屬性:Attribute.GetCustomAttributes() 讀取掛在類別/屬性/方法上的中繼資料

為什麼不需要、也不該自己寫「反射巨集」

自行實現的弊端內建反射的優勢
C# 無前置處理器巨集,只能用原始碼產生器或 Roslyn,複雜度極高零成本、編譯器原生支援、效能經過高度優化
需手動維護字串對應,易出錯、重構時失效強型別、重構安全、IDE 智慧提示完整支援
序列化/反序列化、DI 容器、ORM 等生態皆建立在內建反射之上生態系統完整,Json.NET、Entity Framework、Autofac 等開箱即用
效能差、除錯難、無法享受 JIT 優化內部有快取、動態方法生成(DynamicMethod)、MethodInfo.CreateDelegate 等高效能路徑

實務建議:用 Attribute + Reflection 達成你的需求

若要在屬性上掛載「單位、閾值、讀寫類型」等中繼資料,請定義自訂 Attribute:

[AttributeUsage(AttributeTargets.Property)]
public class MetaAttribute : Attribute {
    public string Unit { get; set; }
    public double Threshold { get; set; }
    public bool ReadOnly { get; set; }
    // 其他需要的中繼資料...
}

public class DeviceConfig {
    [Meta(Unit = "°C", Threshold = 100, ReadOnly = false)]
    public double Temperature { get; set; }

    [Meta(Unit = "kPa", Threshold = 500, ReadOnly = true)]
    public double Pressure { get; set; }
}

執行時讀取:

var props = typeof(DeviceConfig).GetProperties();
foreach (var prop in props) {
    var meta = prop.GetCustomAttribute();
    if (meta != null) {
        Console.WriteLine($"{prop.Name}: Unit={meta.Unit}, Threshold={meta.Threshold}");
    }
}

介面對應函式:直接用介面 + 依賴注入

不用巨集綁 init/run/finalise,定義介面:

public interface ILifecycle {
    void Init();
    void Run();
    void Finalise();
}

public class MyProcessor : ILifecycle {
    public void Init() { /* ... */ }
    public void Run() { /* ... */ }
    public void Finalise() { /* ... */ }
}

搭配 DI 容器(如 Microsoft.Extensions.DependencyInjection)註冊與解析,編譯期型別安全、重構無痛、測試容易。

參考資源

結語

別試圖在 C# 裡發明「反射巨集」。語言設計者已經幫你把最難、最通用、最高效的反射基礎設施寫好、測好、優化好、文件化了。你要做的只是:定義 Attribute 裝中繼資料、定義 Interface 表達契約、用 Reflection API 讀取與驅動。這才是 C# 開發者的正確姿勢。

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