事件本質為方法。定義事件意味著型別具備三種能力:訂閱、取消訂閱、事件發生時通知已訂閱方法。.NET 事件建立在 Delegate 機制之上,採用 Observer 模式。
EventArgs,以 EventArgs 結尾,包含私有欄位與唯讀公用屬性。無附加資料時直接使用 EventArgs 基類。public event EventHandler<NewMailEventArgs> NewMail; 等價於委托宣告 delegate void EventHandler<TVEventArgs>(object sender, TVEventArgs e)。sender 為 object 以相容所有型別;e 繼承 EventArgs 保持一致性;事件方法回傳 void 以利事件鏈操作。protected virtual void OnNewMail(NewMailEventArgs e),使用暫存變數 temp 防止線程同步問題。if (temp != null) temp(this, e);EventArgs 呼叫 OnNewMail。建構函式中 += 訂閱,Unregister 中 -= 取消訂閱。提供回呼方法 FaxMsg(object sender, NewMailEventArgs e)。注意:只能用 +=/-=,不可顯式呼叫 add/remove。事件取消訂閱意義:只要仍有方法訂閱,物件不會被 GC 回收。IDisposable.Dispose 應取消所有事件。
public event EventHandler<T> NewMail 編譯為:私有委托欄位 NewMail = null;add_NewMail(Delegate.Combine);remove_NewMail(Delegate.Remove)。兩方法標記 [MethodImpl(MethodImplOptions.Synchronized)]。event 為 protected/static/virtual 時,兩方法同樣標記。
顯式實作 add/remove 存取器:建立私有委托欄位 m_NewMail 與鎖物件 m_eventLock,在 lock(m_eventLock) 中操作。C# 無法區分編譯器生成與手寫,故仍可用 +=/-=。
Control 擁有 70+ 事件,若全用上述方式會浪費記憶體。解決方案:註冊工廠 + 事件池(詳見設計模式)。