.NET中的事件模式是如何工作的?
事件是一種使用委託的簡化模式。在C#中,所有委託都具有多播能力,即委託的例項不僅可以表示單個方法,還可以表示方法列表。例如:
示例
delegate int Transformer(int x); static void Main(){ Transformer perform = x =>{ int result = x * x; Console.WriteLine(result); return result; }; perform += x =>{ int result = x * x * x; Console.WriteLine(result); return result; }; perform(2); // prints 4 and 8 }
呼叫Perform()會呼叫新增到委託中的所有方法。方法按照新增的順序呼叫。
這允許你實現釋出-訂閱模式,也稱為事件模式。釋出者包含一個委託欄位。它決定何時透過呼叫委託來發布。訂閱者將自己的方法新增到釋出者的委託中,因此每當釋出者決定透過呼叫委託來發布時,它們都會收到通知。訂閱者不知道也不干涉其他訂閱者。
C#事件是一種語言特性,它以型別安全的方式規範了上述模式,從而避免了委託的常見錯誤。事件公開實現事件模式所需的委託功能的子集。下面的示例對此進行了說明。
首先,定義事件發生時要傳送的資料結構。
public class ThresholdReachedEventArgs : EventArgs{ public int Threshold { get; set; } public DateTime TimeReached { get; set; } }
然後,定義釋出者,即想要引發事件的類。
public class Counter{ // 1. Define an event public event EventHandler<ThresholdReachedEventArgs> ThresholdReached; // 2. Do something that raises the event, and pass the EventArgs custom data public void DoSomething(){ ThresholdReachedEventArgs e = new ThresholdReachedEventArgs{ Threshold = 10, TimeReached = DateTime.Now }; // 3. Raise the actual event ThresholdReached?.Invoke(this, e); } }
最後,建立一個或多個訂閱者。想要監聽釋出者引發的事件的類。
class Program{ static void Main(string[] args){ // 1. Create an instance of the publisher, which you want to listen to Counter counter = new Counter(); // 2. Attach an event handler on the publisher counter.ThresholdReached += OnThresholdReached; // 3. Do something that will raise the event. Now you are ready to listen to the event. counter.DoSomething(); } // 4. Handle the event which is raised by publisher static void OnThresholdReached(object sender, ThresholdReachedEventArgs e){ Console.WriteLine($"Reached Threshold {e.Threshold} at {e.TimeReached.ToString()}"); } }
示例
using System; class Program{ static void Main(string[] args){ // 1. Create an instance of the publisher, which you want to listen to Counter counter = new Counter(); // 2. Attach an event handler on the publisher counter.ThresholdReached += OnThresholdReached; // 3. Do something that will raise the event. Now you are ready to listen to the event. counter.DoSomething(); } // 4. Handle the event which is raised by publisher static void OnThresholdReached(object sender, ThresholdReachedEventArgs e){ Console.WriteLine($"Reached Threshold {e.Threshold} at {e.TimeReached.ToString()}"); } } public class ThresholdReachedEventArgs : EventArgs{ public int Threshold { get; set; } public DateTime TimeReached { get; set; } } public class Counter{ // 1. Define an event public event EventHandler<ThresholdReachedEventArgs> ThresholdReached; // 2. Do something that raises the event, and pass the EventArgs custom data public void DoSomething(){ ThresholdReachedEventArgs e = new ThresholdReachedEventArgs{ Threshold = 10, TimeReached = DateTime.Now }; // 3. Raise the actual event ThresholdReached?.Invoke(this, e); } }
輸出
Reached Threshold 10 at 5/15/2021 12:49:10 PM
廣告