久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

面試中的委托

 雄Frank 2012-02-13

4.3  委托(1)

委托技術(shù)是.NET框架中的高級特性之一,,也可以說是.NET重要技術(shù)之一,是在大多數(shù)的技術(shù)筆試,、面試中必定出現(xiàn)的部分,。委托提供了安全的函數(shù)回調(diào)(CALL BACK)機制,成為程序員設(shè)計靈活簡潔的.NET程序的重要方法之一,。本章節(jié)將通過介紹委托概念和分析一些常見的委托技術(shù)題,。

面試題55  什么是委托

.NET面試中經(jīng)常會被提問什么是C#中的委托,面試官主要意圖是考察應(yīng)聘者對.NET的幾個重要特性的了解,。這樣的細(xì)節(jié)問題往往讓程序員不能夠準(zhǔn)確地回答,,讀者應(yīng)該在平時學(xué)習(xí)的過程中注意積累。

【出現(xiàn)頻率】★★★★★

【關(guān)鍵考點】

委托(Delegate)

委托的特點

【考題分析】

委托是一種引用類型,,它是函數(shù)指針的托管版本,。在C#中,委托是一種可以把引用存儲為函數(shù)的類型。委托可以引用實例和靜態(tài)方法,,而函數(shù)指針只能引用靜態(tài)方法,。委托的聲明非常類似函數(shù),和函數(shù)不同的是委托不帶函數(shù)體,,并且需要使用Delegate關(guān)鍵字,。委托的聲明指定了一個函數(shù)簽名,其中包含參數(shù)列表和一個返回類型,。在定義了委托后,,就可以聲明該委托類型的變量,然后可以將這個變量初始化為與該委托有相同簽名的函數(shù)進行引用,,隨后可以使用委托變量調(diào)用該函數(shù),。

注意:委托雖然與函數(shù)指針非常類似,但卻不是指針,。許多程序員把.NET中的委托理解為安全的函數(shù)指針,,這樣的理解是比較牽強的,委托實現(xiàn)的功能和函數(shù)指針非常類似的一點就是提供了程序回調(diào)機制,。

委托的內(nèi)部實現(xiàn)機制和函數(shù)指針在指向方法這一點上是完全相同的,。委托是安全的,主要因為委托和其他所有的.NET成員一樣,,均是一種類型,,都是System.Delegate的某個派生類的一個對象。

現(xiàn)在來分析一個具體的例子,,示例代碼如下:

  1. using System;  
  2. namespace MyConsole  
  3. {  
  4.     class SimpleDelegate  
  5.     {  
  6.         //定義一個返回為double類型的委托,,這個委托有一個整型的輸入?yún)?shù)  
  7.         public delegate double Delegate_Prod(int a);  
  8.         static double fn_Prodvalues(int val1)  
  9.         {  
  10.             return val1 * val1;  
  11.         }  
  12.         static void Main(string[] args)  
  13.         {  
  14. Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);  
  15.                                                 //聲明一個委托  
  16.             Console.Write("請輸入數(shù)字");  
  17.             int v1 = Int32.Parse(Console.ReadLine());  
    //輸入一個整型數(shù)值  
  18.             double res = delObj(v1);               
    //調(diào)用委托方法fn_Prodvalues  
  19.             Console.WriteLine("返回值:" + res);            //返回結(jié)果  
  20.             Console.ReadLine();  
  21.         }  
  22.     }  

示例代碼中,首先通過public delegate double Delegate_Prod(int a)定義了一種名為Delegate_Prod的新類型,,這個類型繼承自System.MulticastDelegate,。它包含一個名為Invoke()的方法,該方法接收一個字符型的參數(shù)且沒有任何返回,。這些步驟都是由C#編譯器自動完成的,。然后,聲明了一個Delegate_Prod的對象delObj,,并且綁定到fn_Prodvalues這個靜態(tài)方法上,。運行結(jié)果如下:

  1. 請輸入數(shù)字9  
  2. 返回值: 81 

注意:本質(zhì)上,委托的調(diào)用就是執(zhí)行了在定義委托時所生成的Invoke()方法,。

C#中的委托類都繼承自System.Delegate類型,。委托類型的聲明與方法簽名相似,有一個返回值和任意數(shù)目任意類型的參數(shù),。委托是一種可用于封裝命名或匿名方法的引用類型,。委托類似于函數(shù)指針,但是委托是類型安全和可靠的。

面試題56  C#中被委托的方法必須是靜態(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)鍵字

不需要static關(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)用時,,需要通過實例對象來訪問,因此綁定實例方法到委托時,,必須同時讓委托得到該實例方法的實例對象的信息,。這樣,.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屬性將會設(shè)置成指向該實例方法所屬類型的一個實例對象,,當(dāng)綁定靜態(tài)方法時,Delegate.Target屬性將會被設(shè)置成null,。

 

4.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)用過程中,委托必須為同類型,,返回類型也必須是void,,且不能帶輸出參數(shù)(但可以帶引用參數(shù)),這樣才能將委托的單個實例合并為一個多播委托,。除此之外,,多番委托的聲明和實例化方法都和其他委托沒有什么不同。現(xiàn)在來看一個實際的例子,,示例代碼如下:

  1. using System;  
  2. namespace MyConsole  
  3. {  
  4.     class MulticastDelegate  
  5.     {  
  6.         //定義委托,,接收一個字符型參數(shù)  
  7.         public delegate void hellokittyHander(string msg);  
  8.         private void hellokitty1(string msg)  
  9.                                     //定義一個簡單
    的私有方法hellokitty1()  
  10.         {  
  11.             Console.WriteLine("hello kitty1" + msg);  
  12.         }  
  13.         private void hellokitty2(string msg)  
  14.                                     //定義一個簡單
    的私有方法hellokitty2()  
  15.         {  
  16.             Console.WriteLine("hello kitty2" + msg);  
  17.         }  
  18.         private void hellokitty3(string msg)  
  19.                                     //定義一個簡單的
    私有方法hellokitty3()  
  20.         {  
  21.             Console.WriteLine("hello kitty3" + msg);  
  22.         }  
  23.         static void Main(string[] args)  
  24.         {  
  25.             MulticastDelegate SimpleDelegate = new
     MulticastDelegate();  
  26.             //聲明一個委托變量,并綁定第一個方法  
  27.             hellokittyHander hellokitty = new 
    hellokittyHander(SimpleDele-  
  28.             gate.hellokitty1);  
  29. hellokitty += new hellokittyHander(SimpleDelegate.hellokitty2);  
  30.                             //綁定第二個方法  
  31. hellokitty += new hellokittyHander(SimpleDelegate.hellokitty3);  
  32.                             //綁定第三個方法  
  33.             //刪除已經(jīng)調(diào)用委托方法  
  34.             hellokitty -new hellokittyHander
    (SimpleDelegate.hellokitty2);  
  35.             if (hellokitty != null)  
  36.                 hellokitty("這是一個委托demo");  
  37.             Console.ReadLine();  
  38.         }  
  39.     }  

簡單分析這個例子,,示例代碼中首先定義了一個帶string參數(shù)無返回的委托hellokittyHander,,在Main()函數(shù)中聲明了一個hellokittyHander的委托變量hellokitty,并綁定了第一個方法void hellokitty1(string msg),。然后,,通過hellokitty += new new hellokittyHander(SimpleDelegate.hellokitty1)初始化了第二個委托,并且綁定了void hellokitty2(string msg) ,,同時把第二個委托掛在第一個委托之后,。緊接著,掛上第三個委托并綁定到 void hellokitty3(string msg),。這是一種比較簡單明了的寫法,,在開發(fā)ASP.NET 或者Windows應(yīng)用程序時,,當(dāng)一個按鈕事件被添加時,Visual Studio就會為程序生成類似的代碼,。

代碼運行結(jié)果如下:

  1. hello kitty1 這是一個委托demo  
  2. hello kitty3 這是一個委托demo 

在這里讀者可能會對這個輸出的代碼產(chǎn)生困惑,,為什么hello kitty2沒有被輸出。事實上細(xì)心的讀者會發(fā)現(xiàn)在上面的程序中有一句取消綁定的事件,,代碼如下:

  1. //刪除已經(jīng)調(diào)用委托方法  
  2. hellokitty -new hellokittyHander
    (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)用是一個比較抽象的問題,,面試官旨在考察應(yīng)聘者對委托的使用經(jīng)驗和設(shè)計能力。為了解釋這一問題,,本小節(jié)將帶領(lǐng)讀者實際體會一個具體的例子。為了能夠熟悉地運用委托,,讀者仍然需要在實際工作學(xué)習(xí)中不斷地積累經(jīng)驗,。

【出現(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)的邏輯,,示例代碼如下:

  1. //學(xué)生類  
  2. class Student  
  3. {  
  4. private string name;                        //姓名字段  
  5. private decimal score;                      //成績字段  
  6. public Student(string name,decimal score)   //構(gòu)造函數(shù),、參數(shù)姓名和成績  
  7. {  
  8.     this.name = name;  
  9.     this.score = score;  
  10. }  
  11. ///比較方法  
  12. ///<param name="lhs">左側(cè)學(xué)生對象</param> 
  13. ///<param name="rhs">右側(cè)學(xué)生對象</param> 
  14. ///<returns>右側(cè)學(xué)生對象的成績高則返回true</returns> 
  15. public static bool RhsIsGreater(object lhs, object rhs)  
  16. {  
  17.     Student studentL = (Student)lhs;  
  18.     Student studentR = (Student)rhs;  
  19.     return (studentR.score > studentL.score) ? true : false;  
  20. }  
  21. ///<returns>預(yù)定義格式的輸出</returns> 
  22. //重寫ToString方法,可以使得輸出更加清晰,,輸出預(yù)定義格式  
  23. public override string ToString()  
  24. {  
  25.     return string.Format(name + " : " + score);  
  26. }  
  27. 4.3  委托(3)

    定義成績排序的委托方法,,并將這個方法添加到委托對象之中。以下示例代碼使用冒泡法排序法對數(shù)組進行排序,。

    1. ///<summary> 
    2. ///排序類,,方法Sort為靜態(tài)方法,,使用冒泡法  
    3. ///</summary> 
    4. class ScoreSort  
    5. {  
    6.     ///<summary> 
    7.     ///冒泡法排序  
    8.     ///</summary> 
    9.     ///<param name="sortArray">要進行排序的數(shù)組</param> 
    10.     ///<param name="Method">排序的方法</param> 
    11.     static public void Sort(object[] sortArray, CompareOp Method)  
    12.     {  
    13.         //外圍第一次循環(huán)  
    14.         for (int i = 0; i < sortArray.Length; i++)  
    15.         {  
    16.             //第二次循環(huán)  
    17.             for (int j = i + 1; j < sortArray.Length; j++)  
    18.             {  
    19.                 //比較大小并交換  
    20.                 if (Method(sortArray[j], sortArray[i]))  
    21.                 {  
    22.                         object temp = sortArray[i];  
    23.                     sortArray[i] = sortArray[j];  
    24.                     sortArray[j] = temp;  
    25.                 }  
    26.             }  
    27.         }  
    28.     }  

    最后可以編寫測試代碼,來測試學(xué)生排序的功能,,示例代碼如下:

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Text;  
    4. namespace MyConsole  
    5. {  
    6.     class StudentSort  
    7.     {  
    8.     //定義一個委托  
    9.     delegate bool CompareOp(object lhs, object rhs);  
    10.         static void Main(string[] args)  
    11.         {  
    12.             //初始化一個學(xué)生數(shù)組  
    13.             Student[] students =  
    14.             {  
    15.                 new Student("Zhang", 86),,  
    16.                 new Student("Li", 75),  
    17.                 new Student("Wang", 93),,  
    18.                 new Student("Zhao", 68),,  
    19.                 new Student("Liu", 53),  
    20.                 new Student("Jia", 100),,  
    21.                 new Student("Pan", 83)  
    22.             };  
    23.             //使用RhsIsGreater方法進行比較,,并用Sort方法排序  
    24.             CompareOp studentCompareOp = new CompareOp(Student.RhsIsGrea-  
    25.             ter);  
    26.             ScoreSort.Sort(students, studentCompareOp);  
    27.             //循環(huán)輸出所有學(xué)生的已排序成績  
    28.             for (int i = 0; i < students.Length; i++)  
    29.             {  
    30.                 Console.WriteLine(students[i].ToString());  
    31.             }  
    32.             Console.ReadLine();  
    33.         }  
    34.     }  

    下面是示例代碼執(zhí)行后的輸出:

    1. Liu: 53  
    2. Zhao: 68  
    3. Li: 75  
    4. Pan: 83  
    5. Zhang: 86  
    6. Wang: 93  
    7. Jia: 100 

    【答案】

    委托的應(yīng)用環(huán)境通常是任務(wù)的執(zhí)行者把細(xì)節(jié)任務(wù)進行再次分配,執(zhí)行者明確地知道被執(zhí)行的工作是什么,,而且可以把這些執(zhí)行細(xì)節(jié)委托給其他組件,、方法或者程序集。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多