下面的程序演示了如何將遵循標準 .NET 模式的事件添加到類和結構中, .NET 類別庫中的所有事件均基于 EventHandler 委托,定義如下:
public delegate void EventHandler(object sender, EventArgs e);
盡管定義的類中的事件可基于任何有效委托型別,甚至是回傳值的委托,但一般還是建議使用 EventHandler 使事件基于 .NET 模式,如下例中所示,
名稱 EventHandler 可能導致一些混淆,因為它不會實際處理事件, EventHandler 和泛型 EventHandler<TEventArgs> 均為委托型別, 其簽名與委托定義匹配的方法或 Lambda 運算式是事件處理程式,并將在引發事件時呼叫,
發布基于 EventHandler 模式的事件
-
(如果無需隨事件一起發送自定義資料,請跳過此步驟轉到步驟 3a,)將自定義資料的類宣告為對發布服務器和訂閱者類均可見的范圍, 然后添加所需成員以保留自定義事件資料, 在此示例中,將回傳一個簡單的字串,
public class CustomEventArgs : EventArgs { public CustomEventArgs(string message) { Message = message; } public string Message { get; set; } }
- (如果使用的是泛型版本 EventHandler<TEventArgs>,請跳過此步驟,)宣告發布類中的委托, 為其指定以
EventHandler結尾的名稱, 第二個引數指定自定義EventArgs型別,public delegate void CustomEventHandler(object sender, CustomEventArgs args);
-
使用下列步驟之一來宣告發布類中的事件,
-
如果沒有任何自定義 EventArgs 類,事件型別將為非泛型 EventHandler 委托, 你無需宣告該委托,因為它已在創建 C# 專案時包括的 System 命名空間中宣告, 將以下代碼添加到發布服務器類,
public event EventHandler RaiseCustomEvent;
- 如果使用非泛型版本 EventHandler 并且具有派生自 EventArgs 的自定義類,請宣告發布類中的事件,并將步驟 2 中的委托用作型別,
public event CustomEventHandler RaiseCustomEvent;
- 如果使用泛型版本,則無需自定義委托, 而是在發布類中,將事件型別指定為
EventHandler<CustomEventArgs>,替換尖括號中自定義類的名稱,public event EventHandler<CustomEventArgs> RaiseCustomEvent;
示例
下例通過使用自定義 EventArgs 類和 EventHandler<TEventArgs> 作為事件型別來演示之前的步驟,
using System; namespace DotNetEvents { // Define a class to hold custom event info public class CustomEventArgs : EventArgs { public CustomEventArgs(string message) { Message = message; } public string Message { get; set; } } // Class that publishes an event class Publisher { // Declare the event using EventHandler<T> public event EventHandler<CustomEventArgs> RaiseCustomEvent; public void DoSomething() { // Write some code that does something useful here // then raise the event. You can also raise an event // before you execute a block of code. OnRaiseCustomEvent(new CustomEventArgs("Event triggered")); } // Wrap event invocations inside a protected virtual method // to allow derived classes to override the event invocation behavior protected virtual void OnRaiseCustomEvent(CustomEventArgs e) { // Make a temporary copy of the event to avoid possibility of // a race condition if the last subscriber unsubscribes // immediately after the null check and before the event is raised. EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent; // Event will be null if there are no subscribers if (raiseEvent != null) { // Format the string to send inside the CustomEventArgs parameter e.Message += $" at {DateTime.Now}"; // Call to raise the event. raiseEvent(this, e); } } } //Class that subscribes to an event class Subscriber { private readonly string _id; public Subscriber(string id, Publisher pub) { _id = id; // Subscribe to the event pub.RaiseCustomEvent += HandleCustomEvent; } // Define what actions to take when the event is raised. void HandleCustomEvent(object sender, CustomEventArgs e) { Console.WriteLine($"{_id} received this message: {e.Message}"); } } class Program { static void Main() { var pub = new Publisher(); var sub1 = new Subscriber("sub1", pub); var sub2 = new Subscriber("sub2", pub); // Call the method that raises the event. pub.DoSomething(); // Keep the console window open Console.WriteLine("Press any key to continue..."); Console.ReadLine(); } } }
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/285379.html
標籤:.NET技术
上一篇:在 Visual Studio 里一秒打開 ILSpy,并反編譯當前專案
下一篇:一探即將到來的 C# 10
