事件的核心價值
- 訊息傳播:發送者不知接收者細節,單向通知
- 鬆散耦合:郵件管理器不直接依賴傳真、手機類別
耦合對比
| 無事件(緊密耦合) | 有事件(鬆散耦合) |
| 發送郵件時直接呼叫 `fax.Send()`、`phone.Notify()` | 發送郵件時僅觸發 `MailArrived` 事件 |
| 新增接收方式需修改郵件管理器 | 新增接收者只需訂閱事件,零修改核心 |
| 難以單元測試郵件管理器 | 可輕易 Mock 事件驗證觸發邏輯 |
事件四要素
- 定義事件:`public event EventHandler MailMsg;`
- 激發事件:`OnMailMsg(e)` 內部檢查 null 後呼叫委派
- 監聽事件:`manager.MailMsg += Handler;`
- 執行事件:處理器邏輯執行
完整程式碼結構回顧
// 1. 事件參數
public class MailMsgEventArgs : EventArgs { ... }
// 2. 郵件管理器(事件源)
public class MailManager
{
public event EventHandler MailMsg;
protected virtual void OnMailMsg(MailMsgEventArgs e) => MailMsg?.Invoke(this, e);
public void SimulateArrivingMsg(...) { OnMailMsg(new MailMsgEventArgs(...)); }
}
// 3. 接收者:傳真、手機
public class Fax { public Fax(MailManager m) => m.MailMsg += FaxMsg; ... }
public class CallPhone { public CallPhone(MailManager m) => m.MailMsg += CellPhoneMsg; ... }
// 4. 客戶端組裝
var mm = new MailManager();
var fax = new Fax(mm, txtBox);
var phone = new CallPhone(mm, txtBox);
mm.SimulateArrivingMsg(...); // 觸發通知
最佳實務提醒
- 事件引數繼承
EventArgs,命名以 EventArgs 結尾
- 激發方法標記
protected virtual 允許衍生類擴充
- 使用
?.Invoke 簡化 null 檢查(C# 6.0+)
- 提供
Register/UnRegister 方法封裝訂閱邏輯
本文配套原始碼下載