委派 是 C# 中極具威力的機制,類似 C/C++ 的函式指標,但更安全、更物件導向。它允許將方法當作參數傳遞、儲存於變數、串聯多個方法(多播委派),並是 事件 機制的基石。本文由淺入深,透過範例說明委派的宣告、實例化、多播與事件模式。
委派定義一種方法簽章(參數與回傳型別),任何符合此簽章的方法都可被委派實例參考。
// 定義:無參數、回傳 string 的委派型別
delegate string MyDelegate();
public class MyClass
{
public string SayHello()
{
return "Hello the world!";
}
}
public class TestMyClass
{
public static void Main()
{
MyClass obj = new MyClass();
// 實例化委派,綁定 obj.SayHello
MyDelegate del = new MyDelegate(obj.SayHello);
// 呼叫委派等同呼叫 obj.SayHello()
Console.WriteLine(del()); // 輸出:Hello the world!
}
}
委派支援 + / - 運算子,可將多個同型別委派組合成一個多播委派,呼叫時依序執行所有封裝的方法。
delegate void MyDelegate(string s);
public class MyClass
{
public void SayHello(string who) => Console.WriteLine(who + " hello!");
public void SayGoodBye(string who) => Console.WriteLine(who + " good bye!");
}
public class TestMyClass
{
public static void Main()
{
MyClass obj = new MyClass();
MyDelegate d1 = new MyDelegate(obj.SayHello);
MyDelegate d2 = new MyDelegate(obj.SayGoodBye);
MyDelegate multi = d1 + d2; // 組合
multi("love.net"); // 依序輸出 hello 與 good bye
}
}
事件 是委派的特殊應用,限制外部只能 +=/-= 訂閱/取消訂閱,不能直接呼叫或覆寫,確保封裝性。事件是 GUI、非同步程式設計的核心。
// 1. 定義事件委派型別
public delegate void EventHandler(string str);
// 2. 事件來源類別
class EventSource
{
// 宣告事件
public event EventHandler Say;
// 觸發事件的方法
public void TriggerEvent()
{
// 安全檢查:有訂閱者才呼叫
if (this.Say != null)
this.Say("A event take place!");
}
}
// 3. 測試
class Test
{
public static void Main()
{
EventSource src = new EventSource();
// 訂閱事件
src.Say += new EventHandler(MyEvent);
// 觸發
src.TriggerEvent();
}
// 事件處理函式
public static void MyEvent(string str)
{
Console.WriteLine(str); // 輸出:A event take place!
}
}
void (object sender, TEventArgs e),便於傳遞豐富資訊。var handler = this.Say;
if (handler != null) handler(this, e);
| 特性 | 委派 | 介面 | 事件 |
|---|---|---|---|
| 用途 | 方法回呼、策略模式 | 定義契約、多型 | 通知、發布-訂閱 |
| 多播 | 支援 | 不支援 | 支援(底層為委派) |
| 封裝性 | 可直接呼叫 | 需實作介面 | 僅能 +=/-= |
委派是 C# 函數式程式設計的基石,事件則是委派在元件通訊上的標準化應用。掌握委派的宣告、實例化、多播與事件模式,能讓你寫出鬆耦合、可擴充的物件導向程式。進階主題包括:Lambda 表達式簡化委派建立、Func/Action 內建委派、非同步委派(BeginInvoke/EndInvoke)與事件存取子自訂。