[.NET] C# 知識回顧 - Event 事件

C# 知識回顧 - Event 事件

【博主】反骨仔    【原文】http://www.cnblogs.com/liqingwen/p/6060297.html  

  昨天,經過《C# 知識回顧 - 事件入門》介紹了事件的定義及簡單用法,今天咱們經過控制檯來看下「發佈 - 訂閱」的基本用法。html

 

目錄

 

1、發佈基於 .NET 類庫的事件

  .NET類庫中的全部事件均基於 EventHandler 委託,定義以下:  ide

public delegate void EventHandler(object sender, EventArgs e);

  你能夠嘗試手動輸入 EventHandler ,而後按下「F12」跳轉到定義:post

 

  .NET 2.0 引入了該委託的一個泛型版本,即 EventHandler<TEventArgs>ui

  【備註】雖然咱們定義的事件能夠基於任何自定的委託類型,但建議使用內置的 EventHandler 進行擴展。
this

 

2、採用 EventHandler 模式發佈事件

  1.這裏選擇繼承了 BCL 中的類 EventArgs,能夠在事件的觸發時進行數據的傳遞。
url

1     class MyEventArgs : EventArgs
2     {
3         public string Message { get; private set; }
4 
5         public MyEventArgs(string message)
6         {
7             Message = message;
8         }
9     }

 

  2.這裏的第二個參數就是自定義的 MyEventArgs 類型,它繼承了 EventArgs。 spa

    delegate void MyEventHandler(object sender, MyEventArgs args);

 

  3.聲明事件的幾種形式:3d

    (1)若是沒有自定義 EventArgs 類,你能夠直接使用 C# 中默認提供的非泛型 EventHandler 委託。
code

public event EventHandler MyEvent;

 

    (2)若是使用的是非泛型的 EventHandler,而且寫了一個自定義由 EventArgs 派生的類,可修改以下。xml

public event MyEventHandler MyEvent;

 

    (3)若是使用的是高級的泛型版本,就不須要自定義委託。你只須要簡單地將事件類型指定爲 EventHandler<MyEventArgs>,將尖括號中的內容替換爲本身的類的名稱。  

public event EventHandler<MyEventArgs> MyEvent;

 

3、一個簡單的發佈訂閱 Demo

  下面的示例經過將自定義的 MyEventArgs 類和 EventHandler<TEventArgs> 進行演示:

This is MyEventArgs.cs  //事件參數
 1     /// <summary>
 2     /// 事件參數
 3     /// </summary>
 4     /// <remarks>一個自定義的類:自定義事件的參數</remarks>
 5     class MyEventArgs : EventArgs
 6     {
 7         public string Message { get; }
 8 
 9         public MyEventArgs(string message)
10         {
11             Message = message;
12         }
13     }

 

This is Publisher.cs  //發佈者
 1     /// <summary>
 2     /// 事件發佈者
 3     /// </summary>
 4     class Publisher
 5     {
 6         //聲明一個泛型事件
 7         public event EventHandler<MyEventArgs> MyEvent;
 8 
 9         public void Publish()
10         {
11             Console.WriteLine("Publis is starting");
12 
13             //你能夠在事件觸發前寫些代碼
14 
15             OnMyEvent(new MyEventArgs(DateTime.Now.ToString()));
16         }
17 
18         /// <summary>
19         /// 觸發事件
20         /// </summary>
21         /// <param name="args"></param>
22         /// <remarks>虛方法,容許子類重寫調用行爲</remarks>
23         protected virtual void OnMyEvent(MyEventArgs args)
24         {
25             //只有在事件訂閱時(!= null),才觸發事件
26             MyEvent?.Invoke(this, args);
27         }
28     }

 

This is Subscriber.cs  //訂閱者
 1     /// <summary>
 2     /// 訂閱者
 3     /// </summary>
 4     class Subscriber
 5     {
 6         public Guid Guid { get; }
 7 
 8         public Subscriber(Publisher publisher)
 9         {
10             Guid = Guid.NewGuid();
11             //使用 C# 2 的語法進行訂閱
12             publisher.MyEvent += Publisher_MyEvent;
13         }
14 
15         /// <summary>
16         /// 事件處理程序
17         /// </summary>
18         /// <param name="sender"></param>
19         /// <param name="args"></param>
20         private void Publisher_MyEvent(object sender, MyEventArgs args)
21         {
22             Console.WriteLine($"    Message is {args.Message}, Guid is {Guid}.");
23         }
24     }

 

This is Program.cs   //控制檯,用於啓動
 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var publisher = new Publisher();
 6             var subscriber1 = new Subscriber(publisher);
 7             var subscriber2 = new Subscriber(publisher);
 8 
 9             //觸發事件
10             publisher.Publish();
11 
12             Console.WriteLine("OK!");
13             Console.Read();
14         }
15     }

 

 

4、實現自定義事件訪問器

  事件一種是特殊類型的多播委託,只能從聲明它的類中進行調用。這些方法須要預先經過事件訪問器添加到委託的調用列表中,事件訪問器跟咱們平時使用的屬性訪問器,特殊的是他們的名字,事件訪問器被命名爲 add 和 remove若是在代碼中沒有提供自定義的事件訪問器,編譯器會自動添加事件訪問器。但在某些狀況下,您可能須要提供自定義的行爲。

 1     class MyClass
 2     {
 3         /// <summary>
 4         /// 5         /// </summary>
 6         private static object Locker = new object();
 7 
 8         /// <summary>
 9         /// 接口
10         /// </summary>
11         public interface IMyEvent
12         {
13             event EventHandler OnCall;
14         }
15 
16         public class MyEvent : IMyEvent
17         {
18             /// <summary>
19             /// 觸發前事件
20             /// </summary>
21             event EventHandler PreEvent;
22 
23             public event EventHandler OnCall
24             {
25                 add
26                 {
27                     lock (Locker)
28                     {
29                         PreEvent += value;
30                     }
31                 }
32                 remove
33                 {
34                     lock (Locker)
35                     {
36                         PreEvent += value;
37                     }
38                 }
39             }
40         }
41     }

 

傳送門

  《C# 知識回顧 - 委託 delegate》、《C# 知識回顧 - 委託 delegate (續)

  《C# 知識回顧 - 事件入門

 


【參考】https://msdn.microsoft.com/zh-cn/library/w369ty8x(v=vs.80).aspx

【參考】微軟官方文檔

相關文章
相關標籤/搜索