閱讀英文

共用方式為


事件簡介

上一個

事件就像委派一樣,延遲綁定 機制。 事實上,事件是以委派的語言支援為基礎所建置。

事件是對象廣播(向系統中所有感興趣的元件)所發生之事件的方式。 任何其他元件都可以訂閱事件,並在引發事件時收到通知。

您可能在某些程式設計中使用事件處理。 許多圖形系統都有事件模型來報告用戶互動。 這些事件會記錄滑鼠移動、滑鼠按鈕的點擊和類似的互動。 這是使用事件的最常見情境之一,但不是唯一的情境。

您可以定義應該針對您的類別引發的事件。 在處理事件時,一個重要考量是,可能尚未針對特定事件註冊任何對象。 您必須撰寫程式代碼,使其不會在未設定接聽程式時引發事件。

訂閱事件也會在兩個物件之間建立關聯(事件來源和事件接收方)。 當您不再對事件感興趣時,要確保事件接收端從事件來源取消訂閱。

事件支援的設計目標

事件的語言設計會以下列目標為目標:

  • 啟用事件來源與事件接收器之間的最小耦合。 這兩個元件可能由不同的組織撰寫,甚至可能以不同的排程更新。
  • 訂閱事件並取消訂閱同一事件應該很簡單。
  • 事件來源應該支援多個事件訂閱者。 它也應該支持沒有附加事件訂閱者。

您可以看到活動的目標相似於委派的目標。 這就是為什麼事件語言支援是建置在委派語言支援之上的原因。

活動的語言支援

事件的定義語法,以及對事件的訂閱或取消訂閱,都是委派語法的延伸。

您可以使用 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 表達式的主體,那麼您就嘗試移除一個從未附加的處理程式,這樣做毫無作用。

在下一篇文章中,您將深入瞭解一般事件模式,以及此範例的不同變化。

下一個