委派是 .NET 型別安全、物件導向的函數指標實現,支援靜態/實例方法、多播與非同步呼叫。本文從背景動機、定義語法、編譯器生成、核心屬性方法、多播實戰與輔助方法完整建立委派基礎認知。
背景:C 函數指標的缺陷
- 僅記憶體位址,無型別資訊(參數型別、個數、回傳型別)
- 呼叫時無法驗證簽名相容性,極易導致執行期崩潰
- 無物件導向封裝,難以管理生命週期
委派定義與三要素
public delegate int Calculate(int x, int y);
封裝三大資訊:
- 方法名稱
- 方法參數(型別、順序、個數)
- 回傳值型別
委派實例可指向靜態方法或實例方法。
編譯器生成機制
編譯器產生繼承 System.MulticastDelegate 的密封類別:
public sealed class Calculate : MulticastDelegate
{
public Calculate(object @object, IntPtr method);
public virtual int Invoke(int x, int y);
public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object @object);
public virtual int EndInvoke(IAsyncResult result);
}
Invoke:同步呼叫
BeginInvoke/EndInvoke:非同步模式(APM)
核心屬性與方法
| 成員 | 型別 | 用途 |
| Method | MethodInfo | 目標方法中繼資料 |
| Target | object | 實例方法的目標物件(靜態方法為 null) |
| GetInvocationList() | Delegate[] | 取得調用鏈中所有委派 |
| Combine | static Delegate | 合併委派(多播) |
| Remove | static Delegate | 移除委派 |
實戰範例:計算器委派
public class Calculator
{
public int Add(int x, int y) => x + y;
public int Subtract(int x, int y) => x - y;
}
public static void DisplayDelegateInfo(Delegate del)
{
foreach (Delegate d in del.GetInvocationList())
{
Console.WriteLine($"Method: {d.Method.Name}, Target: {d.Target}");
}
}
static void Main()
{
Calculator calc = new Calculator();
Calculate c = new Calculate(calc.Add);
Console.WriteLine($"1+1 = {c(1, 1)}"); // 2
c += new Calculate(calc.Subtract); // 多播合併
Console.WriteLine($"1-1 = {c(1, 1)}"); // 0(最後一個委派回傳值)
DisplayDelegateInfo(c);
// 輸出:
// Method: Add, Target: Calculator
// Method: Subtract, Target: Calculator
}
關鍵觀察
- 多播委派調用鏈中所有方法,回傳值為最後一個方法的結果
GetInvocationList 可檢視調用順序與目標
Target 區分實例/靜態方法
下一步:事件與匿名方法
事件建立在委派之上,提供封裝的發布-訂閱介面;匿名方法簡化委派建立語法;Lambda 表達式進一步簡化並支援運算式樹。掌握委派本質是理解後續特性的基石。
- 上一篇文章: C# 3.0 筆記:委派與事件——從委派到事件的語法糖演進
- 下一篇文章: C# 3.0 新體驗:擴充方法深度解析與實戰模式
Copyright ©
程式碼之家 All Rights Reserved