將不確定變成確定~我想監視(shi)我的對象,如果是某(mou)個值,就叫另(ling)一(yi)些方法自(zi)動運行
名(ming)稱有點饒,不是很好理解,但我喜歡(huan)這(zhe)種大白話(hua)(hua),不喜歡(huan)書所翻譯過來的話(hua)(hua),呵呵!
今天(tian)要把(ba)一(yi)(yi)個(ge)不確定的問(wen)題解決,問(wen)題是(shi):一(yi)(yi)個(ge)程序(xu)中,有一(yi)(yi)個(ge)屬性,如果它為true時,我(wo)希望把(ba)另一(yi)(yi)些方法自動運行,這是(shi)可以通過訂(ding)閱事件來(lai)實現的,對嗎?經(jing)過我(wo)的測試確實是(shi)這樣的,呵呵。
事件一(yi)(yi)個一(yi)(yi)直叫(jiao)我們頭痛的話(hua)題,一(yi)(yi)個能不用就不用的東(dong)西,我們程序員為什么那么怕“事件”呢?我來分析幾個原因
1 對本(ben)身(shen)的概念不是(shi)很理(li)解
2 對它的作用不是很清晰,可能書上(shang)說不到點上(shang),個人認(ren)為
3 平時用的少,所以對它更加陌生
今(jin)天,我(wo)就和大家(jia)一起再學習(xi)一個(ge)C#的事(shi)件
一說事(shi)件(jian),就不行不說委托,這(zhe)兩者到(dao)底是(shi)什(shen)么(me)關系呢,在我看來,委托就是(shi)一個類,而事(shi)件(jian)就是(shi)這(zhe)個類的一個實例(li),呵(he)呵(he),這(zhe)樣大家就容易理解了吧
事件(jian)由事件(jian)數據源,事件(jian)所發生的類和事件(jian)訂閱者們組成,“事件(jian)訂閱者們”就是說,一(yi)個事件(jian)可以被多個訂閱都訂閱。
開(kai)始寫代碼了(le),代碼最能說明問(wen)題:
事件源類:
1 /// <summary> 2 /// 事(shi)件(jian)源 3 /// </summary> 4 internal class KeyEventArgs : EventArgs 5 { 6 private char keyChar; 7 public KeyEventArgs(char keyChar) 8 : base() 9 { 10 this.keyChar = keyChar; 11 } 12 13 public char KeyChar 14 { 15 get 16 { 17 return keyChar; 18 } 19 } 20 }
一都(dou)是以EventArgs 結尾的(de),其中EventArgs 本身它是所有事(shi)件源(yuan)類(lei)的(de)基類(lei),它不提供任(ren)何事(shi)件源(yuan)信(xin)息,如果有個性化的(de)事(shi)件信(xin)息,需要(yao)去派生(sheng)它
接下來看(kan),發(fa)生(sheng)(sheng)事件(jian)的(de)類,我(wo)們的(de)事件(jian)就在(zai)這里發(fa)生(sheng)(sheng),在(zai)什(shen)么(me)時候,什(shen)么(me)情(qing)況(kuang)下發(fa)生(sheng)(sheng),都來自這里。
1 /// <summary> 2 /// 事件發生的類(lei) 3 /// </summary> 4 internal class KeyInputMonitor 5 { 6 // 創建一個(ge)委托(tuo),返回類型為avoid,兩個(ge)參數 7 public delegate void KeyDownEventHandler(object sender, KeyEventArgs e); 8 // 將創建的(de)委托和(he)特定事(shi)件(jian)關聯,在這里特定的(de)事(shi)件(jian)為(wei)OnKeyDown 9 public event KeyDownEventHandler OnKeyDown; 10 11 public void Run() 12 { 13 bool finished = false; 14 do 15 { 16 Console.WriteLine("Input a char"); 17 string response = Console.ReadLine(); 18 19 char responseChar = (response == "") ? ' ' : char.ToUpper(response[0]); 20 switch (responseChar) 21 { 22 case 'X': 23 finished = true; 24 break; 25 default: 26 // 得到(dao)按鍵信(xin)息的參(can)數 27 KeyEventArgs keyEventArgs = new KeyEventArgs(responseChar); 28 // 觸發事件 29 OnKeyDown(this, keyEventArgs); 30 break; 31 } 32 } while (!finished); 33 } 34 }
功能就是輸入一個字符,當為X時,退出,當不為X時,去觸發一個事件,事件源數據為“輸入的字符”
到這里,這個事件還沒有任何功能,就相當于,我去賣東西,東西已經擺在臺上了,但還沒有人來買,好,現在是時候有顧客來了
1 /// <summary> 2 /// 顯示(shi)中(zhong)文的接(jie)收類(lei) 3 /// </summary> 4 internal class EventReceiverForChina 5 { 6 public EventReceiverForChina(KeyInputMonitor monitor) 7 { 8 // 產生(sheng)一個委托實例并添(tian)加到KeyInputMonitor產生(sheng)的(de)事件列表(biao)中 9 monitor.OnKeyDown += new KeyInputMonitor.KeyDownEventHandler(this.Echo); 10 } 11 private void Echo(object sender, KeyEventArgs e) 12 { 13 Console.WriteLine("您輸入(ru)的字(zi)條是: {0}", e.KeyChar); 14 } 15 }
這里訂閱(yue)事(shi)件(jian)時,我們使用+=就(jiu)可以了,事(shi)實上(shang)就(jiu)是建(jian)立一個委托類型的新事(shi)件(jian)實例而以。
在前臺調用時,可以這樣:
1 // 實(shi)例化一個事件發(fa)送器,并聲(sheng)明(ming)一個EventReceiverForChina類型的訂閱者 2 KeyInputMonitor monitor = new KeyInputMonitor(); 3 EventReceiverForChina eventReceiverForChina = new EventReceiverForChina(monitor); 4 monitor.Run();
運行的結果就是當你去Run()時,eventReceiverForChina 類型時的某個方法也被執行了,怎么樣,實現了我們今天的話題了吧,其實這就是事件的訂閱機制,事實上在軟件開發中非常有用。 需要注意的是,一般事件的返回類型都是void,當然,這也是很正常的,因為事件就是去做某些事件,它不知道管后果的。呵呵。
祝您晚——來個好夢吧!
回到目錄