事件簡介
事件就像委派一樣,延遲綁定 機制。 事實上,事件是以委派的語言支援為基礎所建置。
事件是對象廣播(向系統中所有感興趣的元件)所發生之事件的方式。 任何其他元件都可以訂閱事件,並在引發事件時收到通知。
您可能在某些程式設計中使用事件處理。 許多圖形系統都有事件模型來報告用戶互動。 這些事件會記錄滑鼠移動、滑鼠按鈕的點擊和類似的互動。 這是使用事件的最常見情境之一,但不是唯一的情境。
您可以定義應該針對您的類別引發的事件。 在處理事件時,一個重要考量是,可能尚未針對特定事件註冊任何對象。 您必須撰寫程式代碼,使其不會在未設定接聽程式時引發事件。
訂閱事件也會在兩個物件之間建立關聯(事件來源和事件接收方)。 當您不再對事件感興趣時,要確保事件接收端從事件來源取消訂閱。
事件的語言設計會以下列目標為目標:
- 啟用事件來源與事件接收器之間的最小耦合。 這兩個元件可能由不同的組織撰寫,甚至可能以不同的排程更新。
- 訂閱事件並取消訂閱同一事件應該很簡單。
- 事件來源應該支援多個事件訂閱者。 它也應該支持沒有附加事件訂閱者。
您可以看到活動的目標相似於委派的目標。 這就是為什麼事件語言支援是建置在委派語言支援之上的原因。
事件的定義語法,以及對事件的訂閱或取消訂閱,都是委派語法的延伸。
您可以使用 event
關鍵字來定義事件:
public event EventHandler<FileFoundArgs>? FileFound;
事件的類型(在此範例中為EventHandler<FileListArgs>
)必須是委派類型。 宣告事件時,您應該遵循慣例。 一般而言,事件委派類型通常會有void返回。 事件宣告應該是動詞或動詞詞組。 當事件報告發生的情況時,請使用過去的時態。 使用目前的時態動詞(例如,Closing
)來報告即將發生的事情。 通常,使用目前的時態表示您的類別支援某種自定義行為。 其中一個最常見的案例是支持取消。 例如,Closing
事件可以包含一個參數,指出關閉作業是否應該繼續或不繼續。 其他案例可讓呼叫端藉由更新事件自變數的屬性來修改行為。 您可以引發事件,指出演算法將採取的下一個動作。 事件處理程式可能會藉由修改事件自變數的屬性來授權不同的動作。
當您想要引發事件時,您可以使用委派調用語法呼叫事件處理程式:
FileFound?.Invoke(this, new FileFoundArgs(file));
如在 委派一節中所述,?.
運算符可讓您輕鬆確保在沒有該事件的訂閱者時,您不會嘗試觸發事件。
您可以使用 +=
運算子來訂閱事件:
var fileLister = new FileSearcher();
int filesFound = 0;
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};
fileLister.FileFound += onFileFound;
處理程式方法通常具有前置詞 'On',後面接著事件名稱,如上述程式代碼所示。
您可以透過使用 -=
運算子來進行取消訂閱的動作:
fileLister.FileFound -= onFileFound;
請務必為代表事件處理程序的表達式宣告局部變數。 這可確保取消訂閱會移除處理程式。 相反地,如果您使用的是 Lambda 表達式的主體,那麼您就嘗試移除一個從未附加的處理程式,這樣做毫無作用。
在下一篇文章中,您將深入瞭解一般事件模式,以及此範例的不同變化。