面試中的委托_第1頁
面試中的委托_第2頁
面試中的委托_第3頁
面試中的委托_第4頁
面試中的委托_第5頁
已閱讀5頁,還剩9頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、面試中的委托4.3委托(1)委托技術(shù)是.NET框架中的高級特性之一,也可以說是.NET重要技術(shù)之一,是在大多數(shù)的技術(shù)筆試、面試中必定出現(xiàn)的部分。委托提供了安全的函數(shù)回調(diào)(CALLBACK)機(jī)制,成為程序員設(shè)計靈活簡潔的.NET程序的重要方法之一。本章節(jié)將通過介紹委托概念和分析一些常見的委托技術(shù)題。面試題55什么是委托.NET面試中經(jīng)常會被提問什么是C#中的委托,面試官主要意圖是考察應(yīng)聘者對.NET的幾個重要特性的了解。這樣的細(xì)節(jié)問題往往讓程序員不能夠準(zhǔn)確地回答,讀者應(yīng)該在平時學(xué)習(xí)的過程中注意積累?!居涩F(xiàn)頻率】【關(guān)鍵考點】委托(Delegate)委托的特點【考題分析】委托是一種引用類型,它是函數(shù)

2、指針的托管版本。在C#中,委托是一種可以把引用存儲為函數(shù)的類型。委托可以引用實例和靜態(tài)方法,而函數(shù)指針只能引用靜態(tài)方法。委托的聲明非常類似函數(shù),和函數(shù)不同的是委托不帶函數(shù)體,并且需要使用Delegate關(guān)鍵字。委托的聲明指定了一個函數(shù)簽名,其中包含參數(shù)列表和一個返回類型。在定義了委托后,就可以聲明該委托類型的變量,然后可以將這個變量初始化為與該委托有相同簽名的函數(shù)進(jìn)行引用,隨后可以使用委托變量調(diào)用該函數(shù)。注意:委托雖然與函數(shù)指針非常類似,但卻不是指針。許多程序員把.NET中的委托理解為安全的函數(shù)指針,這樣的理解是比較牽強(qiáng)的,委托實現(xiàn)的功能和函數(shù)指針非常類似的一點就是提供了程序回調(diào)機(jī)制。委托的內(nèi)

3、部實現(xiàn)機(jī)制和函數(shù)指針在指向方法這一點上是完全相同的。委托是安全的,主要因為委托和其他所有的.NET成員一樣,均是一種類型,都是System.Delegate的某個派生類的一個對象?,F(xiàn)在來分析一個具體的例子,示例代碼如下:usingSystem;namespace MyConsole / 定義一個返回為有一個整型的輸入?yún)?shù)Delegate_Prod(int a);fn_Prodvalues(int val1)val1 * val1;class SimpleDelegatedouble 類型的委托, 這個委托public delegate doublestatic doublereturnstat

4、ic void Main(stringargs)Delegate_ProddelObj=newDelegate_Prod(fn_Prodvalues);/聲明一個委托Console.Write("請輸入數(shù)字");intv1=Int32.Parse(Console.ReadLine();/輸入一個整型數(shù)值doubleres=delObj(v1);/調(diào)用委托方法fn_ProdvaluesConsole.WriteLine("返回值:"+res);/返回結(jié)果Console.ReadLine();示例代碼中,首先通過publicdelegatedoubleDel

5、egate_Prod(inta)定義了一種名為Delegate_Prod的新類型,這個類型繼承自System.MulticastDelegate。它包含一個名為Invoke()的方法,該方法接收一個字符型的參數(shù)且沒有任何返回。這些步驟都是由C#編譯器自動完成的。然后,聲明了一個Delegate_Prod的對象delObj,并且綁定到fn_Prodvalues這個靜態(tài)方法上。運行結(jié)果如下:請輸入數(shù)字9返回值:81注意:本質(zhì)上,委托的調(diào)用就是執(zhí)行了在定義委托時所生成的Invoke()方法。C#中的委托類都繼承自System.Delegate類型。委托類型的聲明與方法簽名相似,有一個返回值和任意數(shù)目

6、任意類型的參數(shù)。委托是一種可用于封裝命名或匿名方法的引用類型。委托類似于函數(shù)指針,但是委托是類型安全和可靠的。面試題56C#中被委托的方法必須是靜態(tài)的嗎關(guān)于委托的方法是否必須是靜態(tài)方法這個考題,考察點非常明確。面試官一般希望了解應(yīng)聘者是不是僅僅了解如何定義和簡單的使用委托,是否真正掌握理解委托的內(nèi)部原理。【由現(xiàn)頻率】【關(guān)鍵考點】靜態(tài)方法與實例方法的區(qū)別分析委托的方法是否必須是靜態(tài)方法【考題分析】在分析這個問題之前,先了解C#幾個基本的概念。在C#中最常見的方法就是靜態(tài)方法和實例方法,它們之間的區(qū)別如表4.1所示。表4.1靜態(tài)方法和實例方法的區(qū)別靜態(tài)方法實例方法Static關(guān)鍵字不需要stati

7、c關(guān)鍵字類名調(diào)用實例對象調(diào)用可以訪問靜態(tài)成員可以直接訪問靜態(tài)成員不可以直接訪問實例成員,需要實例化可以直接訪問靜態(tài)成員不能直接調(diào)用實例方法,需要實例化可以直接調(diào)用實例方法和靜態(tài)方法調(diào)用前初始化實例化時初始化如表4.1所示,在C#中靜態(tài)方法由關(guān)鍵字static來定義。靜態(tài)方法不需要實例化該對象,即可以通過類名來訪問對象。相應(yīng)地,在靜態(tài)方法中不能直接訪問類型中任何非靜態(tài)成員。而實例方法,則需要通過具體的實例對象來調(diào)用,并且可以訪問實例對象中的任何成員對象。委托綁定實例方法的分析,依據(jù)C#實例方法的定義,當(dāng)一個實例方法被調(diào)用時,需要通過實例對象來訪問,因此綁定實例方法到委托時,必須同時讓委托得到該實

8、例方法的實例對象的信息。這樣,.NET才能在委托被回調(diào)(CallBack)的時候成功地執(zhí)行該實例方法。Delegate.Target屬性是一個指向目標(biāo)實例的引用,當(dāng)綁定實例方法給委托時,該參數(shù)會被設(shè)置為該方法所在類型的一個實例對象。委托綁定靜態(tài)方法的分析。Delegate.Target屬性是一個指向目標(biāo)實例的引用,當(dāng)綁定一個靜態(tài)方法給委托時,則該參數(shù)會被設(shè)置為null。注意:如果委托調(diào)用一個或多個實例方法,則此屬性返回調(diào)用列表中最后一個實例方法的目標(biāo)?!敬鸢浮客ㄟ^上面的分析讀者可以清晰地判別,委托不僅能綁定靜態(tài)方法,同時也可綁定實例方法。當(dāng)綁定實例方法時,Delegate.Target屬性將會

9、設(shè)置成指向該實例方法所屬類型的一個實例對象,當(dāng)綁定靜態(tài)方法時,Delegate.Target屬性將會被設(shè)置成null4.3委托(2)面試題57什么是多播委托每個委托都只包含一個方法調(diào)用,調(diào)用委托的次數(shù)與調(diào)用方法的次數(shù)相同。如果要調(diào)用多個方法,就需要多次顯式調(diào)用這個委托。當(dāng)然委托也可以包含多個方法,這種委托稱為多播委托。下面將詳細(xì)分析這個問題。【由現(xiàn)頻率】【關(guān)鍵考點】多播委托的基本概念System.MulticastDelegate的特性【考題分析】在本章前文中,筆者已經(jīng)詳細(xì)地介紹了委托的基本概念。而所謂的多播委托,是指引用多個方法的委托,當(dāng)調(diào)用委托時,它連續(xù)調(diào)用每個方法。在調(diào)用過程中,委托必須

10、為同類型,返回類型也必須是void,且不能帶輸出參數(shù)(但可以帶引用參數(shù)),這樣才能將委托的單個實例合并為一個多播委托。除此之外,多番委托的聲明和實例化方法都和其他委托沒有什么不同?,F(xiàn)在來看一個實際的例子,示例代碼如下:usingSystem;namespaceMyConsoleclassMulticastDelegate/定義委托,接收一個字符型參數(shù)publicdelegatevoidhellokittyHander(stringmsg);privatevoidhellokitty1(stringmsg)/定義一個簡單的私有方法hellokitty1()Console.WriteLine(&q

11、uot;hellokitty1"+msg);privatevoidhellokitty2(stringmsg)/定義一個簡單的私有方法hellokitty2()Console.WriteLine("hellokitty2"+msg);privatevoidhellokitty3(stringmsg)/定義一個簡單的私有方法hellokitty3()Console.WriteLine("hellokitty3"+msg);staticvoidMain(stringargs)MulticastDelegateSimpleDelegate=newMu

12、lticastDelegate();/聲明一個委托變量,并綁定第一個方法hellokittyHanderhellokitty=gate.hellokitty1);newhellokittyHander(SimpleDele-hellokitty+=newhellokittyHander(SimpleDelegate.hellokitty2);/綁定第二個方法hellokitty+=newhellokittyHander(SimpleDelegate.hellokitty3);/綁定第三個方法/刪除已經(jīng)調(diào)用委托方法hellokitty-=newhellokittyHander(SimpleDel

13、egate.hellokitty2);if(hellokitty!=null)hellokitty("這是一個委托demo");Console.ReadLine();簡單分析這個例子,示例代碼中首先定義了一個帶string參數(shù)無返回的委托hellokittyHander,在Main()函數(shù)中聲明了一個hellokittyHander的委托變量hellokitty,并綁定了第一個方法voidhellokitty1(stringmsg)。然后,通過hellokitty+=newnewhellokittyHander(SimpleDelegate.hellokitty1)初始化了

14、第二個委托,并且綁定了voidhellokitty2(stringmsg),同時把第二個委托掛在第一個委托之后。緊接著,掛上第三個委托并綁定到voidhellokitty3(stringmsg)。這是一種比較簡單明了的寫法,在開發(fā)ASP.NET或者Windows應(yīng)用程序時,當(dāng)一個按鈕事件被添加時,VisualStudio就會為程序生成類似的代碼。代碼運行結(jié)果如下:hellokitty1這是一個委托demohellokitty3這是一個委托demo在這里讀者可能會對這個輸出的代碼產(chǎn)生困惑,為什么hellokitty2沒有被輸出。事實上細(xì)心的讀者會發(fā)現(xiàn)在上面的程序中有一句取消綁定的事件,代碼如下:

15、/刪除已經(jīng)調(diào)用委托方法hellokitty-=newhellokittyHander(SimpleDelegate.hellokitty2);注意:多播委托是指一個委托的鏈表,而不是指另一類特殊的委托。當(dāng)執(zhí)行鏈上的一個方法,后續(xù)委托方法將會依次被執(zhí)行。System.MulticastDelegate定義了對多播委托的支持?!敬鸢浮慷嗖ノ惺侵敢粋€由委托串成的鏈表,當(dāng)鏈表上的一個委托被回調(diào)時,所有鏈表上該委托的后續(xù)委托將會被順序執(zhí)行。但要注意,多播委托必須是同類型的,返回類型必須是void,并且不能帶輸出參數(shù)(但可以帶引用參數(shù))。面試題58列舉一個C#中的委托應(yīng)用列舉C#中的委托應(yīng)用是一個比較抽

16、象的問題,面試官旨在考察應(yīng)聘者對委托的使用經(jīng)驗和設(shè)計能力。為了解釋這一問題,本小節(jié)將帶領(lǐng)讀者實際體會一個具體的例子。為了能夠熟悉地運用委托,讀者仍然需要在實際工作學(xué)習(xí)中不斷地積累經(jīng)驗?!居涩F(xiàn)頻率】【關(guān)鍵考點】委托的設(shè)計委托的應(yīng)用【考題分析】排序系統(tǒng)在大多數(shù)系統(tǒng)中都有所應(yīng)用,在本小節(jié)中,筆者將舉一個學(xué)生成績排序的例子來說明委托的實際應(yīng)用。下列代碼展示了這個學(xué)生成績排序系統(tǒng)的簡單實現(xiàn)方式。示例中定義了學(xué)生類型的基本成員、構(gòu)造方法,在私有構(gòu)造方法中,為學(xué)生排序委托定義了默認(rèn)的邏輯,示例代碼如下:/學(xué)生類classStudentprivatestringname;/姓名字段privatedecimal

17、score;/成績字段publicStudent(stringname,decimalscore)/構(gòu)造函數(shù)、參數(shù)姓名和成績=name;this.score=score;/比較方法/<paramname="lhs">左側(cè)學(xué)生對象</param>/<paramname="rhs">右側(cè)學(xué)生對象</param>/<returns>右側(cè)學(xué)生對象的成績高則返回true</returns&

18、;gt;publicstaticboolRhsIsGreater(objectlhs,objectrhs)StudentstudentL=(Student)lhs;StudentstudentR=(Student)rhs;return(studentR.score>studentL.score)?true:false;/<returns>預(yù)定義格式的輸出</returns>/重寫ToString方法,可以使得輸出更加清晰,輸出預(yù)定義格式publicoverridestringToString()returnstring.Fo

19、rmat(name+":"+score);4.3委托(3)定義成績排序的委托方法,并將這個方法添加到委托對象之中。以下示例代碼使用冒泡法排序法對數(shù)組進(jìn)行排序。/<summary>/排序類,方法Sort為靜態(tài)方法,使用冒泡法/</summary>classScoreSort/<summary>/冒泡法排序/</summary>/<paramname="sortArray">要進(jìn)行排序的數(shù)組</param&

20、amp;gt;/<paramname="Method">排序的方法</param>staticpublicvoidSort(objectsortArray,CompareOpMethod)/外圍第一次循環(huán)for(inti=0;i<sortArray.Length;i+)/第二次循環(huán)for(intj=i+1;j<sortArray.Length;j+)/比較大小并交換if(Method(sortArrayj,sortArrayi)objecttemp=sortArrayi;sortArrayi=sortArrayj;sortArrayj=temp;最后可以編寫測試代碼,來測試學(xué)生排序的功能,示例代碼如下:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceMyConsoleclassStudentSort/定義一個委托delegateboolCom

溫馨提示

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

最新文檔

評論

0/150

提交評論