備註
此內容經Pearson Education, Inc.授權從架構設計指導方針:可重複使用 .NET 程式庫的慣例、習慣用語與範式 (第2版)轉載。 該版於2008年出版,該書自那以後已於 第三版全面修訂。 此頁面的某些資訊可能已過期。
事件是最常使用的回呼形式(可讓架構呼叫使用者程式代碼的建構)。 其他回呼機制包括接受委派函式的成員、虛擬成員,以及基於介面的外掛程式。可用性研究的數據指出,大部分開發人員更習慣使用事件,而非其他回呼機制。 事件與 Visual Studio 和許多語言完美整合。
請務必注意,有兩組事件:在系統狀態變更之前引發的事件、稱為預先事件,以及在狀態變更之後引發的事件,稱為後事件。 一個事件發生前的範例是 Form.Closing,它會在窗體關閉之前被觸發。 事件觸發後的範例為 Form.Closed,在表單關閉後引發。
✔️ 在描述事件時請使用「raise」一詞,而不是「fire」或「trigger」。
✔️ DO 使用 System.EventHandler<TEventArgs> 而不是手動建立要當做事件處理程式的新委派。
✔️ 請考慮使用 的子類別 EventArgs 做為事件自變數,除非您絕對確定事件永遠不需要將任何數據傳送至事件處理方法,在此情況下,您可以直接使用 EventArgs 類型。
如果您直接使用 EventArgs 寄送 API,您將永遠無法新增任何要與事件一起攜帶的數據,而不會中斷相容性。 如果您使用子類別,即使一開始是完全空白,您仍可在需要時將屬性新增至子類別。
✔️ DO 使用受保護的虛擬方法來引發每個事件。 這隻適用於未密封類別上的非靜態事件,不適用於結構、密封類別或靜態事件。
方法的目的是要提供一個方法,讓衍生類別使用覆寫來處理事件。 覆寫是一種更有彈性、更快速且更自然的方式來處理衍生類別中的基類事件。 依照慣例,方法的名稱應該以 「On」 開頭,後面接著事件的名稱。
衍生類別可以選擇不在其覆寫中呼叫 方法的基底實作。 請準備好,確保在方法中不包含基類正常運作所需的任何處理。
✔️ DO 傳遞一個參數給用於觸發事件的保護方法。
參數應該命名為 e,而且其類型應該是事件參數類別。
❌ 引發非靜態事件時,請勿以傳送者身分傳遞 Null。
✔️ 當引發靜態事件時,請將 null 作為 sender 參數傳遞。
❌ 引發事件時,請勿傳遞 Null 做為事件數據參數。
如果您不想將任何數據傳遞至事件處理方法,則應該傳遞 EventArgs.Empty 。 開發人員預期此參數不是 Null。
✔️ 請考慮引發最終使用者可以取消的事件。 這僅適用於事前活動。
使用 System.ComponentModel.CancelEventArgs 或其子類別做為事件自變數,以允許使用者取消事件。
自訂事件處理程序設計
在某些情況下,EventHandler<T> 無法使用,例如當框架需要與不支援泛型的舊版 CLR 一起工作時。 在這種情況下,您可能需要設計和開發自定義事件處理程式委派。
✔️ 請將事件處理常式的傳回類型設為 void。
事件處理程式可以在多個物件上叫用多個事件處理方法。 如果允許事件處理方法傳回值,則每個事件調用都會有多個傳回值。
✔️ DO 使用 object 做為事件處理程式第一個參數的類型,並呼叫它 sender。
✔️ DO 使用 System.EventArgs 或其子類別做為事件處理程式的第二個參數類型,並呼叫它 e。
❌ 事件處理程式上不要有兩個以上的參數。
© 2005年、2009年Microsoft公司部分。 保留所有權利。
經 Pearson Education, Inc. 許可重新刊登自 Krzysztof Cwalina 和 Brad Abrams 所著的 架構設計指導方針: 可重複使用的 .NET 程式庫慣例、慣用語和模式,第 2 版,2008 年 10 月 22 日由 Addison-Wesley Professional 發行,作為 Microsoft Windows 開發系列的一部分。