關(guān)于委托,肯定是要有問題的。
關(guān)于事件。
關(guān)于Lambda。
由上面的那個(gè)偽代碼就能看得出來,委托其實(shí)是和類在一個(gè)層次的東西,它還有基類,兩個(gè)基類:System.MulticastDelegate和System.Delegate基類。簡單的委托實(shí)例(兩個(gè)數(shù)的加法):
怎么干?委托在底層,實(shí)際上在MulticastDelegate派生類上調(diào)用了編譯器生成的invoke方法。說下委托的類型安全:如果試圖將一個(gè)不匹配的方法傳入委托,就會收到編譯錯(cuò)誤(例如上面的委托你傳入一個(gè)參數(shù)的方法。)
定義委托,來判斷,當(dāng)加速的時(shí)候,會不會超過最大值而崩潰:
下面是加速方法,當(dāng)速度不同的時(shí)候輸出一些不同的信息:
在PRogram的Main方法里面每次加速 二十,并且記錄每次加速之后的輸出:
調(diào)用結(jié)果如下:
由上,可以總結(jié)出委托通知的步驟:定義將通知發(fā)送給調(diào)用者的委托類型。聲明每個(gè)委托類型成員變量。在淚殤創(chuàng)建輔助函數(shù)使調(diào)用者能指定由委托成員變量保存的方法。修改方法,在適當(dāng)?shù)那樾蜗抡{(diào)用委托中的調(diào)用列表。
Car中的方法修改:
調(diào)用代碼:
結(jié)果:
同理,如果是想要移除方法,用-=操作符就可以了。相當(dāng)于退訂功能。
泛型委托提供了更靈活的方式來指定類型安全的形式進(jìn)行調(diào)用的方法。之前,我們一般通過使用System.Object參數(shù)來達(dá)到相似的目的:public delegate void MyDelegate(object arg);盡管如此,但是我們會因此失去類型安全并且可能還會有裝箱損失。
下面是修改之后的加速方法:
由此可以看來,事件只是節(jié)省了鍵入事件,下面說說如何在調(diào)用者這邊監(jiān)聽傳入的事件。C#事件也簡化了注冊調(diào)用者事件處理程序的操作。現(xiàn)在無需指定自定義輔助方法,調(diào)用者僅需使用+=和-=操作符即可(操作符將在后臺觸發(fā)正確的add_xxx()方法或remove_xxx()方法)。使用C#的事件注冊語法修改Main方法如下:
當(dāng)然,我們也可以用方法組轉(zhuǎn)換語法。就不再陳述。
所以,如果我們?nèi)绻獋鬟f自定義數(shù)據(jù),那么就需要?jiǎng)?chuàng)建一個(gè)派生自EventArgs的類。如下:
我們修改委托,增添一個(gè)CarEventArgs參數(shù),就可以傳遞數(shù)據(jù)了。(事件不變。)public delegate void CarEngineHandler(object sender, CarEventArgs args);//定義委托調(diào)用方法: if (Exploded != null) { Exploded(this,new CarEventArgs("Sorry, this car is dead...")); }如何接受者想與發(fā)送事件的對象交互,我們可以現(xiàn)實(shí)強(qiáng)制轉(zhuǎn)換System.Object。這樣就可以使用傳遞給事件通過對象中的任何公共成員。
匿名方法非常有趣,它使我們能訪問定義他們的方法的本地變量。這些變量成為匿名方法的外部變量。有關(guān)匿名方法和定義方法的作用域之間的交互,有幾個(gè)重要的知識點(diǎn):匿名方法不能訪問定義方法中的ref或out參數(shù)。匿名方法中的本地變量不能與外部方法中的本地變量重名。匿名方法可以訪問外部類作用域中的實(shí)例變量(或靜態(tài)變量)。新聞熱點(diǎn)
疑難解答
圖片精選