事件簡介
事件就像委派,是「晚期繫結」機制。 事實上,事件是建立在委派的語言支援上。
事件一種物件 (向系統中所有感興趣的元件) 廣播有事發生的方式。 任何其他元件皆可以訂閱事件,並在引發事件時收到通知。
您可能在自己的某些程式設計中使用過事件。 許多圖形系統都有報告使用者互動的事件模型。 這些事件會報告滑鼠移動、按下按鈕和類似的互動。 這是其中最常見的,但不是使用事件的唯一狀況。
您可以為您的類別定義應該引發的事件。 處理事件時有一項重要考量,就是特定事件可能沒有任何登錄的物件。 您必須撰寫程式碼,讓它在未設定任何接聽程式時不會引發事件。
訂閱事件也會建立兩個物件 (事件來源和事件接收) 的結合程度。 您需要確保,對事件不再感興趣時,事件接收會取消訂閱事件來源。
事件支援的設計目標
事件目標的語言設計有下列目標:
讓事件來源和事件接收之間的結合程度降至最低。 這兩個元件可能不是由相同的組織所撰寫,甚至可能依完全不同的排程更新。
訂閱事件應該非常簡單,取消訂閱相同事件也一樣。
事件來源應該支援多個事件訂閱者。 它也應該支援不附加任何事件訂閱者。
您可以看到事件的目標與委派的目標非常相似。 這就是事件語言支援建立在委派語言支援上的原因。
事件語言支援
定義事件以及訂閱或取消訂閱事件的語法,是委派的語法延伸模組。
若要定義事件請使用 event
關鍵字︰
public event EventHandler<FileListArgs> Progress;
事件類型 (本例中為 EventHandler<FileListArgs>
) 必須是委派類型。 宣告事件時應該遵循一些慣例。 一般而言,事件委派類型具有 void 傳回。
事件宣告應該是動詞或動詞片語。
當事件報告過去發生的事件時,請使用過去式。 報告將要發生的事件時,請使用現在式動詞 (例如,Closing
)。 通常使用現在式是表示您的類別支援某類的自訂行為。 最常見的情況之一就是支援取消。 例如,Closing
事件可包括一個引數,指出關閉作業是否應該繼續。 其他情況可讓呼叫端更新事件引數的屬性以修改行為。 您可引發事件,指出演算法會採用的下一個提議動作。 事件處理常式可透過修改事件引數的屬性來要求不同的動作。
當您想要引發事件時,可使用委派引動過程語法呼叫事件處理常式︰
Progress?.Invoke(this, new FileListArgs(file));
如上一節中討論的委派,?。 當該事件沒有訂閱者時,運算子讓您輕鬆確定不用嘗試引發事件。
使用 +=
運算子訂閱事件︰
EventHandler<FileListArgs> onProgress = (sender, eventArgs) =>
Console.WriteLine(eventArgs.FoundFile);
fileLister.Progress += onProgress;
處理常式方法通常具有前置詞 ‘On' 後面接事件名稱,如上所示。
使用 -=
運算子取消訂閱事件:
fileLister.Progress -= onProgress;
您宣告表示事件處理常式的運算式區域變數極為重要。 這可確保取消訂閱移除處理常式。 但若改用 Lambda 運算式的主體,就要嘗試移除永遠不會附加的處理常式,其不執行任何作業。
在下一篇文章中,您會深入了解一般的事件模式,以及本例的不同變化。