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

.NET 反射與委派技術在設計模式中的應用實戰

     編輯:關於.NET

反射技術與設計模式

.NET 可執行程式結構層級

AppDomain → Assembly → Module → Type → Member。反射封裝各層級物件,支援運行時:

  • 載入組件、列舉型別、建立實例
  • 檢視/調用方法、屬性、欄位、事件、建構子
  • 讀取自訂屬性

反射核心 API 對照表

目標反射類別常用方法
組件AssemblyLoadFrom, GetTypes, CreateInstance
型別TypeGetMethods, GetProperties, GetConstructors
方法MethodInfoInvoke, GetParameters, ReturnType
屬性PropertyInfoGetValue, SetValue, PropertyType
欄位FieldInfoGetValue, SetValue, FieldType
事件EventInfoAddEventHandler, RemoveEventHandler
建構子ConstructorInfoInvoke, GetParameters
參數ParameterInfoName, ParameterType, IsIn/IsOut

反射範例:動態列舉、建立、調用

Assembly asm = Assembly.LoadFrom("ReflectionExample.exe");
foreach (Type t in asm.GetTypes()) Console.WriteLine(t.Name);

Type helloType = typeof(HelloWorld);
foreach (MethodInfo mi in helloType.GetMethods()) Console.WriteLine(mi.Name);

object obj = Activator.CreateInstance(helloType);
object objWithArg = Activator.CreateInstance(helloType, new object[] { "zhenlei" });

MethodInfo sayHello = helloType.GetMethod("SayHello");
sayHello.Invoke(obj, null);
sayHello.Invoke(objWithArg, null);

反射簡化設計模式實作

模式傳統痛點反射優化
工廠方法每新增產品類別需修改工廠代碼配置檔存儲型別名,工廠通用 Activator.CreateInstance
抽象工廠產品族擴充需新增多個工廠子類反射動態組裝產品族,減少子類爆炸
命令模式命令類別與調用者強耦合以命令型別名為鍵動態建立並執行
享元模式享元工廠需管理大量具體類別反射按需實例化,簡化工廠邏輯

委派技術與設計模式

.NET 委派本質

  • 型別安全的函數指標,繼承自 MulticastDelegate。
  • 封裝靜態/實例方法,支援多播(調用列表)。
  • 核心:Invoke(同步)、BeginInvoke/EndInvoke(非同步 APM 模式)。
  • 與 C++ 函數指標異:面向物件、型別安全、支援實例方法(隱含 this)。

委派聲明與使用

// 聲明
delegate float CompareFunc(float a, float b);

// 使用
public class TemplateProcessor
{
    public CompareFunc Comparer { get; set; }

    public float Process(float[] data)
    {
        float result = float.NaN;
        foreach (var v in data)
            result = float.IsNaN(result) ? v : Comparer(result, v);
        return result;
    }
}

// 客戶端動態綁定
var proc = new TemplateProcessor();
proc.Comparer = (a, b) => Math.Max(a, b); // Lambda 最大值
float max = proc.Process(new[] { 1f, 5f, 3f }); // 5

proc.Comparer = (a, b) => a + b; // 累加
float sum = proc.Process(new[] { 1f, 2f, 3f }); // 6

委派 vs GoF 委派模式

GoF 《設計模式》中的「委派」指物件組合:接受請求的物件將操作轉交給委派物件,並傳遞 this 使委派能回呼。.NET 委派更進一步:

  • 解耦合:調用者完全不知曉目標方法所屬類別。
  • 動態綁定:運行時決定綁定哪個方法,無需繼承體系。
  • 多播:一個委派可串聯多個處理者(事件模型基礎)。
// GoF 風格:Window 持有 Rectangle 參考
window.Area = new Rectangle().Area; // 需引用 Rectangle 類別

// .NET 委派風格:Window 僅持有委派
public delegate float AreaCalculator();
public class Window { public AreaCalculator CalcArea; }

// 運行時綁定
var rect = new Rectangle();
var win = new Window();
win.CalcArea = new AreaCalculator(rect.CalculateArea); // 動態綁定,無編譯期依賴

委派簡化設計模式

模式委派應用
模板方法以委派注入變化步驟,替代繼承重寫,支援運行時組合
觀察者事件本質即多播委派,event 關鍵字封裝加減訂閱
中介者同事類透過委派與中介者通訊,移除雙向引用
策略委派即輕量級策略介面,無需定義介面與實作類

綜合實戰:插件式規則引擎

// 規則介面(委派版)
public delegate bool RuleEvaluator(Context ctx);

// 規則載入器(反射版)
public class RuleLoader
{
    public IEnumerable LoadRules(string assemblyPath)
    {
        Assembly asm = Assembly.LoadFrom(assemblyPath);
        foreach (Type t in asm.GetTypes())
        {
            if (t.IsClass && !t.IsAbstract && typeof(IRule).IsAssignableFrom(t))
            {
                IRule rule = (IRule)Activator.CreateInstance(t);
                yield return rule.Evaluate; // 方法組成委派
            }
        }
    }
}

// 執行引擎
public class RuleEngine
{
    private List _rules = new List();

    public void AddRule(RuleEvaluator rule) => _rules.Add(rule);

    public bool ExecuteAll(Context ctx) => _rules.All(r => r(ctx));
}

總結

  • 反射解決「型別未知/動態載入/結構探查」問題,是框架級開發的利器。
  • 委派解決「行為參數化/動態綁定/事件通知」問題,是業務邏輯組合的核心。
  • 兩者結合,可構建高擴展、低耦合、配置驅動的系統架構。
  • 濫用反射影響效能與可讀性,建議:框架層多用,業務層慎用;委派則大力推薦用於策略、模板、事件等場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved