標籤:style 使用 strong ar 問題 line new size
假設沒有事件,我們能不能通過委託實現事件的功能?事實上是可以的。下面我們一步一步剖析!先舉個例子:
有這麼一個情境,有一個氣球(相當於事件、訊息的寄件者),氣球爆炸(相當於觸發事件),小孩子聽到氣球爆炸會嚇哭(小孩子相當於一個事件的訂閱者)。我們不適用事件,使用委託來完成這個程式。
第一步:定義一個全域的委託類型, public delegate void BombEventHandler();//定義了一個委託,其實是一個類吧,相當於一個委託類
第二步:定義氣球類(BalloonPublisher),很簡單,這個類僅僅用友一個爆炸的方法,爆炸就發出訊息,我爆炸了,也就是調用bomb委託
public class BalloonPublisher
{ public BombEventHandler Bomb;//委託類型的變數
public void BalloonBomb()
{
if (Bomb != null)
{
Bomb();//調用委託
}
}
}
第三步:我們實現訂閱者,小孩子類,為了簡單我們僅僅定義一個被嚇哭的方法
public class ChildrenSubscribe
{
//其實訂閱委託
public void OnHearBomb()
{
Console.WriteLine("我被爆炸傷嚇哭了");
}
}
一切定義好了,就等著關聯了,用戶端進行關聯:
static void Main(string[] args)
{
//用戶端觸發事件,並訂閱事件
BalloonPublisher pb = new BalloonPublisher();
ChildrenSubscribe sb = new ChildrenSubscribe();
pb.Bomb += sb.OnHearBomb; //是不是很熟悉?關鍵氣球爆炸委託和小孩子聽到爆炸後的方法
pb.BalloonBomb();//觸發爆炸事件,其實是執行委託
}
執行結果很明白,當爆炸觸發時候,小孩子嚇哭這個方法也在這個委託鏈上所以也就執行了嚇哭方法。
回顧下上面的過程,和事件功能完全一樣,說明委託完全可以實現事件的功能!可是為什麼會有事件的產生呢?對上面的例子我們可以這麼想,氣球爆炸是屬於氣球本身的,與用戶端沒關係,只有氣球才能觸發爆炸這個方法,可是我們上面這個例子是可以通過用戶端直接觸發氣球爆炸的,比如 pb.Bomb();直接觸發爆炸委託,也能把小孩嚇哭。這樣就破壞了封裝性。這是事件產生的第一個原因。
假如氣球爆炸後,不僅僅引起小孩子哭,還會引起大人尋找那的氣球爆炸了,周圍的鳥也會飛走等一系列事件。這就需要把這些方法都得加入到委託連pb.Bomb中去。
如果用戶端不小心把把這個委託連弄斷了或者改變了,將會引起很大的麻煩,所有訂閱的類都失敗了。
為瞭解決以上問題,事件才應運而生的,其實事件就是對委託的封裝罷了,具體內部實現我就不多說了,網上多的是。
下面給出利用事件完成此功能的程式:其實很簡單,把氣球類裡面的委託換成事件定義即可,這樣以後,你在用戶端 直接調用pb.BombEvent();是有語法錯誤的,從而確保了封裝性和事件也只能有氣球本身觸發,與用戶端沒任何關係
public class BalloonPublisher
{
public event BombEventHandler BombEvent; //我加了Event的尾碼
public void BalloonBomb()
{
if (BombEvent != null)
{
BombEvent();//調用委託
}
}
}