[C#.NET] 建議 - 應該實現標準的事件模組寫法

  • 11167
  • 0
  • C#
  • 2012-08-13

[C#.NET] 建議 - 應該實現標準的事件模組寫法

我透過ReSharper,想要得知事件的宣告標準規則寫法。

我對按鈕控制項的Click按下F12

SNAGHTMLc535ccf

於是我得到了。

public event EventHandler Click

SNAGHTMLc547e24

而 EventHandler 的委派原型長得如下,這也是絕大部份 .NET BCL 所使用的原型。

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

SNAGHTMLc43ed3b

sender,所代表的就是事件的觸發者,button就是觸發者

e,所代表的就是事件參數,按扭按下去就是事件參數

EventArgs 則是事件的參數的基礎原型

SNAGHTMLc560c40

用來觸發事件的OnClick方法

SNAGHTMLc76426d

如果還看不太懂,我們再來看 textBox 的 MouseDown事件好了

SNAGHTMLc51164e
MouseEventHandler 原型長這樣
public delegate void MouseEventHandler(object sender, MouseEventArgs e);

SNAGHTMLc51eb58

MouseEventArgs 事件參數長這樣

SNAGHTMLc575d6b

再多看看幾個控制項類別以及方法,就會規納出幾個重點

  1. 事件委派的命名以 EventHandler 結尾
  2. 事件委派的簽章不返回任何資料型態,即宣告成 void
  3. 事件委派委派的簽章具有兩個參數,sender 表示事件觸發者;e 表示事件參數
  4. 事件參數的命名以 EventArgs 結尾
  5. 事件觸發的方法命名以 On 為開頭,用來引發事件用。

更多的資源可以參考下篇,由上圖可以得知,微軟是遵守其規則。

http://msdn.microsoft.com/zh-tw/library/ms229011.aspx



接下來,練習一下剛剛的規則啦~
Step1.建立 ConnectCompletedEventArgs 類別,並繼承 EventArgs
{
    private bool _isConnected;

    public bool IsConnected
    {
        get { return _isConnected; }
        set { _isConnected = value; }
    }
}
Step2.建立Reader類別,分別建立 ConnectCompletedEventHandler 委派和 ConnectCompleted 事件
public event ConnectCompletedEventHandler ConnectCompleted;

 

Step3.在Reader類別,建立公開的Connect方法及受保護的OnConnect方法
{
    ConnectCompletedEventArgs e = new ConnectCompletedEventArgs();
    //模擬長時間作業
    Thread.Sleep(10000);

e.IsConnected = true; this.OnConnect(e); } protected virtual void OnConnect(ConnectCompletedEventArgs e) { if (ConnectCompleted != null) { ConnectCompleted(this, e); } }
最後完成的程式碼如下:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace RfidReader
{
    public class Reader
    {
        public delegate void ConnectCompletedEventHandler(object sender, ConnectCompletedEventArgs e);
 
        public event ConnectCompletedEventHandler ConnectCompleted;
 
        public void Connect()
        {
            ConnectCompletedEventArgs e = new ConnectCompletedEventArgs();
            //模擬長時間作業
            Thread.Sleep(10000);
e.IsConnected = true; this.OnConnect(e); } protected virtual void OnConnect(ConnectCompletedEventArgs e) { if (ConnectCompleted != null) { ConnectCompleted(this, e); } } } public class ConnectCompletedEventArgs : EventArgs { private bool _isConnected; public bool IsConnected { get { return _isConnected; } set { _isConnected = value; } } } }
Step4.在Client呼叫端就可以使用 += 來註冊(訂閱) ConnectCompleted 事件。
{
    Reader reader = new Reader();
    reader.ConnectCompleted += new Reader.ConnectCompletedEventHandler(reader_ConnectCompleted);
    reader.Connect();
}

private void reader_ConnectCompleted(object sender, ConnectCompletedEventArgs e)
{
    MessageBox.Show(e.IsConnected.ToString());
}

然而,MSDN上又建議我們『要使用 System.EventHandler<T>,而不要手動建立新的委派來當做事件處理常式使用。』
所以把 Step2. 上的委派(delegate)刪掉,把事件宣告改成以下:
 
Client的註冊改成以下:

                    

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo