今天用C#2.0的泛型改寫了我的一個系統的消息實現,感覺非常不錯,很簡潔而且速度快了(MSDN上那麼說的,暗示誘導使我也有此感覺,呵呵)。
我們唠會兒嗑,回顧一下經典內容:
.Net框架的消息模型,構建於一個連接事件句柄的代理(
delegate),要想觸發某個事件,兩個基本元素是必須考慮的:
1、事件的源頭觸發者,它定義了一個事件:
public class EventSender
{
...
//聲明一個代理類型,本例中,它指向一個無返回值的方法,並有兩個參數
public delegate void MyEventHandler(obejct sender, EventArgs e);
//由該代理實例化一個事件成員
public event MyEventHandler myEvent;
...
//在某個地方根據邏輯觸發(Fire)這個事件
//即向系統告知:“老大您聽好了,我發出了一個事件”
this.myEvent(this,null);
...
}
2、事件的接收者,它注冊了該事件
public class EventReceiver
{
……
//實例化上面的事件發出者類
EventSender sender = new EventSender();
//注冊EventSender的myEvent事件,即向系統告知:“如果這個對象發出了該事件,我很樂意接受”
//同時告知系統:“老大,在下我有能力並且迫切需要通過我的OnReceivedTheEvent方法處理該事件”
sender.myEvent += new MyEventHandler(OnReceivedTheEvent);
……
private void OnReceivedTheEvent(object sender, EventArgs e)
{
//實現自己的處理
}
}
當然,如果我們不需要傳遞自定義的(繼承的)
EventArgs,我們可以用系統已經定義的一個消息代理
EventHandler直接去實例化一個事件成員,從而省去了定義代理類型的步驟。這種情況下,觸發事件的目的僅僅是起到通知的作用,不能傳遞運行時數據(因為
System.EventArgs是最基本的事件參數類,其他事件參數類都是繼承該類,比如
MouseEventArgs),沒有能力容納用戶自定義信息,比如您想在觸發事件的同時,傳遞該對象的某個狀態值... System.EventArgs無能為力。
上面所說的是經典的事件處理模式,在C#2.0中,事件處理引入了泛型機制,從而大為便捷了我們的編程。與此配套,
EventHandler有了它的泛型版本
EventHandler<T>。
下面我們通過兩個版本的代碼片斷來比較泛型給我們帶來的視覺沖擊和編程享受: -)
任務:定義和注冊三個事件,分別使用三個不同的EventArgs繼承對象傳遞不同的數據
//c#1.1
……//定義(在假定類MyClass中)
Public delegate void MyEventHandler1(object sender, MyEventArgs1 myEventArgs1);
Public delegate void MyEventHandler2(object sender, MyEventArgs2 myEventArgs2);
Public delegate void MyEventHandler3(object sender, MyEventArgs3 myEventArgs3);
public event MyEventHandler1 event1;
public event MyEventHandler2 event2;
public event MyEventHandler3 event3;
……
//注冊(假定了實例化MyClass)
myClass.event1 += new EventHandler(
this,myEventArgs1);
myClass.event2 += new EventHandler(
this, myEventArgs1);
myClass.event3 += new EventHandler(
this, myEventArgs1);
//C# 2.0
……//定義(在假定類MyGoodClass中)
public event EventHandler< MyEventArgs1> event 1;
public event EventHandler< MyEventArgs2> event 2;
public event EventHandler< MyEventArgs3> event 3;
……
//注冊(假定了實例化MyGoodClass)
myGoodClass.event1 += new EventHandler< MyEventArgs1>(this,myEventArgs1);
myGoodClass.event2 += new EventHandler< MyEventArgs2>(this,myEventArgs2);
myGoodClass.event3 += new EventHandler< MyEventArgs3>(this,myEventArgs3);
對比可以發現,代碼是不是簡潔了不少?其實泛型的優點和用途遠遠不止這些。它還有一個很大的好處就是類型安全和線程安全,以往我們需要傳遞通用數據時,往往使用object類型,雖然這種方法在技術上是可行的,但是系統在裝箱和拆箱上的開銷以及類型轉換上的風險(InvalidCastException)卻有相當的弊端。