1. 委托(Delegate)
定義與作用
- ?委托?是類型安全的函數指針,用于封裝方法,支持多播(鏈式調用)。
- ?核心能力?:將方法作為參數傳遞或異步回調。
使用場景
- 回調機制(如異步操作完成通知)。
- 實現策略模式(動態替換算法邏輯)。
- LINQ查詢中的條件篩選(
Where(x => x > 6)
)。 - 多播委托(多個方法依次執行)。
示例代碼
// 定義委托
public delegate void LogHandler(string message);
/ 使用委托public class Processor
{ public void RunTask(LogHandler logger)
{ logger("Task started.");
// ...業務邏輯 logger("Task completed.");
}
} // 調用方
var processor = new Processor();
processor.RunTask(message => Console.WriteLine($"[LOG] {message}"));
2. 事件(Event)
定義與作用
- ?事件?是基于委托的語法糖,強制封裝性,遵循?發布-訂閱模式?。
- ?核心規則?:只能在聲明類內部觸發(
Invoke
),外部僅能+=
或-=
訂閱。
使用場景
- GUI事件(按鈕點擊、鼠標移動)。
- 觀察者模式(狀態變化通知)。
- 松耦合系統(組件間通信)。
示例代碼
// 定義事件public class OrderService
{
public event EventHandler<OrderEventArgs> OrderSubmitted;
public void SubmitOrder(Order order)
{
// ...提交訂單邏輯
OnOrderSubmitted(new OrderEventArgs(order));}
protected virtual void OnOrderSubmitted(OrderEventArgs e)
{ OrderSubmitted?.Invoke(this, e); } }
// 訂閱事件 var service = new OrderService();service.OrderSubmitted += (sender, e) => {
Console.WriteLine($"Order {e.OrderId} submitted!");};
3. 委托與事件的關系
?特性? | ?委托? | ?事件? |
---|---|---|
封裝性 | 可被外部直接調用 | 只能在聲明類內觸發 |
多播 | 支持 | 支持 |
安全性 | 低(外部可修改委托鏈) | 高(外部僅訂閱/取消) |
典型用途 | 靈活的方法傳遞 | 系統級通知(如UI交互) |
關鍵點總結
- ?委托是基礎?:事件本質是受限的委托,編譯器自動生成
add/remove
方法。 - ?設計原則?:
- 事件用于?被動通知?(如用戶操作)。
- 委托用于?主動傳遞邏輯?(如回調函數)。
- ?代碼規范?:事件命名使用
動詞
(如Clicked
/DataReceived
),委托命名用Handler
后綴。
疑問與解決方案
?Q1:為什么事件比委托更安全??
A1:事件禁止外部直接賦值(=
操作符),強制通過+=
和-=
管理訂閱,避免覆蓋其他訂閱者。
?Q2:何時選擇自定義委托而非Action/Func
??
A2:需要明確語義時
(如public delegate void PriceChangedHandler(double oldPrice)
優于Action<double>
)。