《Effective C#》Item 21:用委托实现回调
委托屬于C#中的新名詞,它的應(yīng)用也非常廣泛,例如事件就是委托最簡(jiǎn)單而又直接的例子。
?
那么首先說(shuō)說(shuō)什么是委托,其實(shí)委托在用過(guò)C或者C++的人看來(lái)就是函數(shù)指針,不過(guò)使用C#的大多數(shù)人都沒(méi)有用過(guò)這兩門(mén)語(yǔ)言,因此對(duì)委托的理解不是很深,對(duì)于委托可以簡(jiǎn)單的從字面去理解,即“委托別人去執(zhí)行某些操作”,也就是說(shuō)執(zhí)行一個(gè)操作,而這個(gè)操作過(guò)程自身并不知道,只是委托過(guò)來(lái)讓你去執(zhí)行而已。
參看如下這個(gè)例子。
??? public delegate void HelloHandler( string Msg );
??? private void SayHello( string sMsg )
??? {
??????? MessageBox.Show( sMsg );
??? }
??? // delegate sample
??? HelloHandler hHello = new HelloHandler( SayHello );
??? hHello( "Hello World!" );
?
例子很明顯,在執(zhí)行hHello的時(shí)候,并不知道具體的過(guò)程是什么樣的,只是去執(zhí)行而已。
現(xiàn)在要說(shuō)說(shuō)委托能做些什么,那么先來(lái)分析一下事件,這也是委托用得最多的地方。一般事件的初始化需要綁定一個(gè)事件處理函數(shù),那么當(dāng)事件觸發(fā)的時(shí)候,處理函數(shù)會(huì)被調(diào)用,也就是說(shuō)在事件處理函數(shù)可以明確的知道,此事件是被觸發(fā)了。例如,點(diǎn)擊窗體的上的Button,它會(huì)把Click事件反饋給窗體。很明顯,委托是處理對(duì)象之間的信息交互。除了事件外,委托的大多用處都和此類似,那么這樣使用的好處在于降低對(duì)象之間耦合性。
?
其次委托不同于以前函數(shù)指針的地方在于,可以綁定多個(gè)委托函數(shù),例如:
??? public delegate void HelloHandler( string Msg );
??? private void WriteHello1( string sMsg )
??? {
??????? Debug.WriteLine( "WriteHello1:" + sMsg );
??? }
??? private void WriteHello2( string sMsg )
??? {
??????? Debug.WriteLine( "WriteHello2:" + sMsg );
??? }
??? // delegate sample
??? HelloHandler hHello = new HelloHandler( WriteHello1 );
??? hHello += new HelloHandler( WriteHello2 );
??? hHello( "Hello World!" );
?
不過(guò)在這種情況下,由于綁定到委托上的函數(shù)是按照順序執(zhí)行的,所以有兩個(gè)潛在的問(wèn)題。
第一個(gè)問(wèn)題,當(dāng)一個(gè)函數(shù)執(zhí)行過(guò)程中產(chǎn)生異常,導(dǎo)致后面的不能進(jìn)行執(zhí)行。就上面的例子而言,如果在“WriteHello1”函數(shù)中出現(xiàn)異常,會(huì)導(dǎo)致“WriteHello2”不能被執(zhí)行。
另一個(gè)問(wèn)題,就是委托執(zhí)行的返回值,當(dāng)綁定多個(gè)函數(shù),委托執(zhí)行的返回值是最后一個(gè)綁定函數(shù)執(zhí)行后的返回值,那么通過(guò)這個(gè)值去做判斷將會(huì)是不正確的。
那么對(duì)于委托綁定多個(gè)函數(shù),要注意的是不要把異常擴(kuò)散出來(lái),其次委托類型的返回值為“void”。
?
如何去使用委托,很多人看了書(shū)上的例子,也知道委托的意義,但是無(wú)法把它和實(shí)際應(yīng)用進(jìn)行結(jié)合。那么在使用委托的時(shí)候,首先要明白幾個(gè)問(wèn)題,等各個(gè)問(wèn)題清楚了,委托原型也就自然出來(lái)了。
需要分析清楚的問(wèn)題有如下幾點(diǎn)。
問(wèn)題一,傳遞信息是什么,傳遞的時(shí)機(jī)是否固定,一次傳遞還是多次傳遞;
問(wèn)題二,用委托是否合適;
問(wèn)題三,哪一方是委托的調(diào)用端,而哪一方是委托的初始端;
問(wèn)題四,委托的初始化放在哪里比較合適。
?
問(wèn)題一是關(guān)鍵,這首先決定是否要使用委托來(lái)實(shí)現(xiàn),其次如果要使用委托,那么需要確定委托函數(shù)類型。
對(duì)于問(wèn)題二來(lái)說(shuō),很多人可能就不解了。沒(méi)錯(cuò),委托是可以降低類型之間的耦合性,但是能起到這種作用的并不是只有委托這一種方法。很多情況下,用重載構(gòu)造函數(shù)即可以達(dá)到這一目的,因此想問(wèn)題的時(shí)候,不能局限于此。例如,很多人都做過(guò)彈出一個(gè)單獨(dú)窗體對(duì)某一條記錄進(jìn)行修改,這里用委托可以實(shí)現(xiàn),但是考慮到DataRow屬于引用類型,而這個(gè)窗體脫離了數(shù)據(jù)記錄就失去了意義,因此可以重載構(gòu)造函數(shù),在初始化窗體的時(shí)候,把記錄傳遞給窗體就行了。相對(duì)而言,后者會(huì)更簡(jiǎn)單直接些。
有了前兩個(gè)問(wèn)題的分析,不少人在寫(xiě)委托的時(shí)候,會(huì)把順序?qū)懛戳?#xff0c;因此程序執(zhí)行的效果并不是設(shè)想中的那樣,這一點(diǎn)要尤為注意。
對(duì)于第四個(gè)問(wèn)題來(lái)說(shuō),可以借鑒窗體的控件事件初始化部分代碼,即委托的初始化采取就近原則,不過(guò)這不是唯一初始化的地方,這樣寫(xiě)只是便于防止漏寫(xiě)。
?
好了,對(duì)于委托大致說(shuō)這么多,希望對(duì)大家有所幫助。
?
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/Knight94/archive/2006/11/15/1385284.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/Sue_/articles/1656797.html
總結(jié)
以上是生活随笔為你收集整理的《Effective C#》Item 21:用委托实现回调的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 经桥科技与湖南文化艺术产业集团合力打造“
- 下一篇: 明天一定要记得放一个硬币在口袋