委托與事件定義
public delegate void MailMsgEventHandler(object sender, MailMsgEventArgs e);
public class MailManager
{
public event MailMsgEventHandler MailMsg; // 事件
protected virtual void OnMailMsg(MailMsgEventArgs e)
{
MailMsg?.Invoke(this, e); // C# 6.0+ null 條件運算子
}
public void SimulateArrivingMsg(string from, string to, string subject, string body)
{
var e = new MailMsgEventArgs(from, to, subject, body);
OnMailMsg(e);
}
}
傳真接收者實作
public class Fax
{
private readonly TextBox _tBox;
public Fax(MailManager mm, TextBox tBox)
{
_tBox = tBox;
mm.MailMsg += FaxMsg; // 訂閱
}
private void FaxMsg(object sender, MailMsgEventArgs e)
{
_tBox.Text += $"消息到傳真:\n來自:{e.from}\n發到:{e.to}\n主題:{e.subject}\n內容:{e.body}\n\n";
}
public void Register(MailManager mm) => mm.MailMsg += FaxMsg;
public void UnRegister(MailManager mm) => mm.MailMsg -= FaxMsg;
}
事件參數類別
public class MailMsgEventArgs : EventArgs
{
public readonly string from, to, subject, body;
public MailMsgEventArgs(string from, string to, string subject, string body)
{
this.from = from; this.to = to; this.subject = subject; this.body = body;
}
}
關鍵細節
- `event` 關鍵字限制外部只能 `+=`/`-=`,不能直接賦值或 `Invoke`
- `OnMailMsg` 為 `protected virtual`,衍生類可擴充觸發前後邏輯
- 接收者持有 `TextBox` 參考更新 UI,實務上建議用 `SynchronizationContext` 或 `Invoke` 確保執行緒安全
- 提供 `Register`/`UnRegister` 封裝訂閱,支援動態啟用/停用