C中的委托的使用和講解_第1頁
C中的委托的使用和講解_第2頁
C中的委托的使用和講解_第3頁
C中的委托的使用和講解_第4頁
C中的委托的使用和講解_第5頁
免費預覽已結束,剩余5頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、引言委托和事件在.NetFramework中的應用非常廣泛,然而,較好地理解委托和事件對很多接觸C#時間不長的人來說并不容易。它們就像是一道檻兒,過了這個檻的 人,覺得真是太容易了,而沒有過去的人每次見到委托和事件就覺得心里別( bi e) 得慌,混身不自在。本文中,我將通過兩個范例由淺入深地講述什么是委托、為什 么要使用委托、事件的由來、.NetFramework中的委托和事件、委托和事件對Observer設計模式的意義,對它們的中間代碼也做了討論。將方法作為方法的參數我們先不管這個標題如何的繞口,也不管委托究竟是個什么東西,來看下面這兩個 最簡單的方法,它們不過是在屏幕上輸出一句問候的話語

2、:1publicvoid GreetPeople( string name)2/做某些額外的事情,比如初始化之類,此處略 3En glishGreeti ng(n ame);41publicvoid EnglishGreeting( string name)2Co nsole.WriteL in e( "Morni ng," +n ame);3調用 EnglishGreeting暫且不管這兩個方法有沒有什么實際意義。 Greet People用于向某人問好,當我們 傳遞代表某人姓名的name參數,比如說“JiYF;'進去的時候,在這個方法中,將則用于向方法,再次傳遞

3、 name 參數,EnglishGreeting“Morning ”Greet ing屏幕輸出 “Morning,JiYF ”。現在假設這個程序需要進行全球化, 哎呀,不好了,我是中國人,我不明白 是什么意思,怎么辦呢?好吧,我們再加個中文版的問候方法:1publicvoid ChineseGreeting( string name) 2Console.WriteLine("早上好,"+name);3這時候,Greet People 也需要改一改了,不然如何判斷到底用哪個版本的 問候方法合適呢?在進行這個之前,我們最好再定義一個枚舉作為判斷的依據:1publicenum L

4、anguage2En glish,Ch in ese31publicvoid GreetPeople( string name,Languagelang)2做某些額外的事情,比如初始化之類,此處略3swith(la ng)4caseLa nguage.E nglish: 5En glishGreeti ng(n ame); 6break;7caseLa nguage.Ch in ese: 8Chi neseGreeti ng( name); 9break;1011OK,盡管這樣解決了問題,但我不說大家也很容易想到,這個解決方案的可擴展性很差,如果日后我們需要再添加韓文版、日文版,就不得不反復修

5、改枚舉和Greet Peop le()方法,以適應新的需求。在考慮新的解決方案之前,我們先看看Greet Peo ple的方法簽名:1publicvoid GreetPeople( string name,Languagelang)我們僅看stringname ,在這里,string是參數類型,name是參數變量,當我們 賦給name字符串“jimmy”時,它就代表“jimmy”這個值;當我們賦給它張子陽” 時,它又代表著 張子陽”這個值。然后,我們可以在方法體內對這個name進行其他操作。哎,這簡直是廢話么,剛學程序就知道了。它又代,那給這個等)?如果你再仔細想想,假如 Greet Peop

6、 le()方法可以接受一個參數變量,這個變量可 以代表另一個方法,當我們給這個變量賦值En glishGreet ing的時候,它代表著EnglsihGreeting()這個方法;當我們給它賦值 ChineseGreeting的時候,表著ChineseGreeting() 方法。我們將這個參數變量命名為MakeGreeting么不是可以如同給name賦值時一樣,在調用GreetPeople()方法的時候, MakeGreeting參數也賦上值么(ChineseGreeting或者 EnglsihGreetingMakeGreet ing。但是,(比如然后,我們在方法體內,也可以像使用別的參數一

7、樣使用由于MakeGreeting代表著一個方法,它的使用方式應該和它被賦的方法Chin eseGreeti ng) 是一樣的,比如:1 MakeGreet ing(n ame);好了,有了思路了,我們現在就來改改Greet Peop le()方法,那么它應該是這個樣子了:1publicvoid GreetPeople( string name,*MakeGreeting) 2MakeGreeti ng(n ame);3注意到*,這個位置通常放置的應該是參數的類型,但到目前為止,我們僅僅是 GreetPeople 方法,現在 參數應該是什么類型想到應該有個可以代表方法的參數,并按這個思路去改寫

8、 就出現了一個大問題:這個代表著方法的MakeGreeti ng 的?NOTE :這里已不再需要枚舉了,因為在給MakeGreeting使用哪個方法,是 ChineseGreeting還是 EnglishGreeting內部,已經對使用“morning”還是 早上好”作了區分。賦值的時候動態地決定,而在這個兩個方法ChineseGreeting()禾R EnglishGreeting()聰明的你應該已經想到了,現在是委托該出場的時候了,但講述委托之前,我們再 看看MakeGreeting 參數所能代表的方法的簽名:P ublicvoid En glishGreet ing( stri ng p

9、ublicvoid ChineseGreeting( string 如同name可以接受String類型的 int 類型的 1 一樣。MakeGreeting MakeGreet ingn ame)n ame)“true和“ 1;但不能接受bool類型的true和 的參數類型定義應該能夠確定可以代表的方法種類,再進一步講,就是MakeGreeting可以代表的方法的參數類型和返回類型。于是,委托出現了:它定義了 MakeGreeting參數所能代表的方法的種類,也就是MakeGreeting參數的類型。NOTE :如果上面這句話比較繞口,我把它翻譯成這樣:string定義了 name參數所能代

10、表的值的種類,也就是name參數的類型。本例中委托的定義:1P ublicdelegatevoidGreet in gDelegate( stri ng n ame);可以與上面EnglishGreeting()方法的簽名對比一下,除了加入了delegate 關鍵字以外,其余的是不是完全一樣? 現在,讓我們再次改動 Greet Peopl e()方法,如下所示: 1 publicvoid GreetPeople( string name,GreetingDelegateMakeGreeting) 2MakeGreeti ng(n ame);3如你所見,委托Greet in gDelegate

11、型,那么 GreetingDelegate 聲明方式和類卻完全不同,譯成類。因為Delegate 更多的內容將在下面講述,出現的位置與string相同,string是一個類 應該也是一個類型,或者叫類(Class)。但是委托的 這是怎么一回事?實際上,委托在編譯的時候確實會編 是一個類,所以在任何可以聲明類的地方都可以聲明委托。 現在,請看看這個范例的完整代碼:1using System;2us ing3using System.Text;45n ames pace)elegate6定義委托,它定義了可以代表的方法的類型7p ublicdelegatevoid8class Program910

12、p rivatestaticvoid11Co nsole.WriteLi ne(121314p rivatestaticvoidGreetingDelegate( string name);EnglishGreeting( string name) "Morni ng," +n ame);ChineseGreeting( string name)15Console.WriteLine("早上好,"+name);161718注意此方法,它接受一個 Greet in gDelegate類型的方法作為參數19privatestaticvoidGreetPeop

13、le( string name,GreetingDelegateMakeGreeting)20MakeGreet in g( name);212223staticvoid Main(string args)24GreetPeople( "JimmyZhang",EnglishGreeting);25GreetPeople("張子陽",ChineseGreeting);26Co nsole.ReadKeyO;272829輸出如下:Morni ngJmmyZha ng早上好,張子陽 我們現在對委托做一個總結:委托是一個類,它定義了方法的類型,使得可以將方法當

14、作另一個方法的參數來進 行傳遞,這種將方法動態地賦給參數的做法,可以避免在程序中大量使用 If-Else(Switch)語句,同時使得程序具有更好的可擴展性。將方法綁定到委托看到這里,是不是有那么點如夢初醒的感覺?于是,你是不是在想:在上面的例子 中,我不一定要直接在 GreetPeople()方法中給name參數賦值,我可以像這樣使 用變量:1 staticvoid Main(string args)2string name1,name2;3n ame1=JimmyZha ng"4name2="張子陽"56Greet Peop le( name1,E nglis

15、hGreet in g);7Greet Peop le( name2,Chi neseGreet in g); 8Co nsole.ReadKeyO;9而既然委托Greet in gDelegate和類型string的地位一樣,都是定義了一種參數類型,那么,我是不是也可以這么使用委托?1 staticvoid Main(string args)2Greeti ngDelegatedelegate1,delegate2;3delegate仁E nglishGreeti ng; 4delegate2=Chi neseGreeti ng;56GreetPeople( "JimmyZhang

16、",delegate1);7GreetPeople("張子陽",delegate2);8Co nsole.ReadKeyO;9如你所料,這樣是沒有問題的,程序一如預料的那樣輸出。這里,我想說的是委托 不同于string的一個特性:可以將多個方法賦給同一個委托,或者叫將多個方法綁 定到同一個委托,當調用這個委托的時候,將依次調用其所綁定的方法。在這個例 子中,語法如下:1 staticvoid Main(string args)2Greeti ngDelegatedelegate1;3delegate1=EnglishGreeting;/先給委托類型的變量賦值4de

17、legate1+=ChineseGreeting; /給此委托變量再綁定一個方法 56 將先后調用 EnglishGreeting 與 ChineseGreeting 方法 7GreetPeople( "JimmyZhang",delegate1);8Co nsole.ReadKeyO;9輸出為:Morni ngJmmyZha ng早上好 JimmyZhang實際上,我們可以也可以繞過 Greet Peo ple方法,通過委托來直接調用EnglishGreeting禾口 ChineseGreeting:1 staticvoidMain(string args)2Greeti

18、 ngDelegatedelegate1;3delegate1=EnglishGreeting;/先給委托類型的變量賦值4delegate1+=ChineseGreeting; /給此委托變量再綁定一個方法56/ 將先后調用 EnglishGreeting 與 ChineseGreeting 方法7delegate1( "JimmyZhang");8Co nsole.ReadKeyO;9NOTE :這在本例中是沒有問題的,但回頭看下上面GreetPeople()的定義,在它之中可以做一些對于 EnglshihGreeting禾口 ChineseGreeting來說都需要進行

19、的工作,為了簡便我做了省略。注意這里,第一次用的“二”是賦值的語法;第二次,用的是“ +二”,是綁定的語法。 如果第一次就使用“ +二”,將出現使用了未賦值的局部變量”的編譯錯誤。我們也可以使用下面的代碼來這樣簡化這一過程:1 Greeti ngDelegatedelegate1= n ewGreet in gDelegate(E nglishGreeti ng); 2delegate1+=ChineseGreeting; /給此委托變量再綁定一個方法看到這里,應該注意到,這段代碼第一條語句與實例化一個類是何其的相似,你不 禁想到:上面第一次綁定委托時不可以使用“ +二”的編譯錯誤,或許可以用這樣的方法來避免:1 Greeti ngDelegatedelegate仁 2delegate1+=E nglishGreet ing; 3delegate1+=Chi neseGreet ing;n ewGreet in gDelegate();/這次用的是“ += ”,綁定語法。/給此委托變量再綁定一個方法“GreetingDelegate ”方法沒有采用“O'個參數的但是編譯的提示:沒有0個參數的重 我知道你一定按捺不住想探

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論