事件的由來(lái)
我們繼續(xù)思考上面的程序:上面的三個(gè)方法都定義在Programe類中,這樣做是為了理解的方便,實(shí)際應(yīng)用中,通常都是 GreetPeople 在一個(gè)類中,ChineseGreeting和 EnglishGreeting 在另外的類中,F(xiàn)在你已經(jīng)對(duì)委托有了初步了解,是時(shí)候?qū)ι厦娴睦幼鰝(gè)改進(jìn)了。假設(shè)我們將GreetingPeople()放在一個(gè)叫GreetingManager的類中,那么新程序應(yīng)該是這個(gè)樣子的:
namespace Delegate { //定義委托,它定義了可以代表的方法的類型 public delegate void GreetingDelegate(string name); //新建的GreetingManager類 public class GreetingManager{ public void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } }
class Program { private static void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); }
private static void ChineseGreeting(string name) { Console.WriteLine("早上好, " + name); }
static void Main(string[] args) { // ... ... } } }
這個(gè)時(shí)候,如果要實(shí)現(xiàn)前面演示的輸出效果,Main方法我想應(yīng)該是這樣的:
static void Main(string[] args) { GreetingManager gm = new GreetingManager(); gm.GreetPeople("Jimmy Zhang", EnglishGreeting); gm.GreetPeople("張子陽(yáng)", ChineseGreeting); }
我們運(yùn)行這段代碼,嗯,沒(méi)有任何問(wèn)題。程序一如預(yù)料地那樣輸出了: Morning, Jimmy Zhang 早上好, 張子陽(yáng)
現(xiàn)在,假設(shè)我們需要使用上一節(jié)學(xué)到的知識(shí),將多個(gè)方法綁定到同一個(gè)委托變量,該如何做呢?讓我們?cè)俅胃膶懘a:
static void Main(string[] args) { GreetingManager gm = new GreetingManager(); GreetingDelegate delegate1; delegate1 = EnglishGreeting; delegate1 += ChineseGreeting;
gm.GreetPeople("Jimmy Zhang", delegate1); }
輸出: Morning, Jimmy Zhang 早上好, Jimmy Zhang
到了這里,我們不禁想到:面向?qū)ο笤O(shè)計(jì),講究的是對(duì)象的封裝,既然可以聲明委托類型的變量(在上例中是delegate1),我們何不將這個(gè)變量封裝到 GreetManager類中?在這個(gè)類的客戶端中使用不是更方便么?于是,我們改寫GreetManager類,像這樣:
public class GreetingManager{ //在GreetingManager類的內(nèi)部聲明delegate1變量 public GreetingDelegate delegate1;
public void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } }
現(xiàn)在,我們可以這樣使用這個(gè)委托變量:
static void Main(string[] args) { GreetingManager gm = new GreetingManager(); gm.delegate1 = EnglishGreeting; gm.delegate1 += ChineseGreeting;
gm.GreetPeople("Jimmy Zhang", gm.delegate1); }
盡管這樣達(dá)到了我們要的效果,但是似乎并不美氣,光是第一個(gè)方法注冊(cè)用“=”,第二個(gè)用“+=”就讓人覺(jué)得別扭。此時(shí),輪到Event出場(chǎng)了,C# 中可以使用事件來(lái)專門完成這項(xiàng)工作,我們改寫GreetingManager類,它變成了這個(gè)樣子:
public class GreetingManager{ //這一次我們?cè)谶@里聲明一個(gè)事件 public event GreetingDelegate MakeGreet;
public void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } }
很容易注意到:MakeGreet 事件的聲明與之前委托變量delegate1的聲明唯一的區(qū)別是多了一個(gè)event關(guān)鍵字。看到這里,你差不多明白到:事件其實(shí)沒(méi)什么不好理解的,聲明一個(gè)事件不過(guò)類似于聲明一個(gè)委托類型的變量而已。
我們想當(dāng)然地改寫Main方法:
static void Main(string[] args) { GreetingManager gm = new GreetingManager(); gm.MakeGreet = EnglishGreeting; // 編譯錯(cuò)誤1 gm.MakeGreet += ChineseGreeting;
gm.GreetPeople("Jimmy Zhang", gm.MakeGreet); //編譯錯(cuò)誤2 }
這次,你會(huì)得到編譯錯(cuò)誤:事件“Delegate.GreetingManager.MakeGreet”只能出現(xiàn)在 += 或 -= 的左邊(從類型“Delegate.GreetingManager”中使用時(shí)除外)。
出處:藍(lán)色理想
責(zé)任編輯:moby
上一頁(yè) 將方法綁定到委托 下一頁(yè) 事件和委托的編譯代碼
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|