不懼面試:委託

原文地址:不懼面試:委託html

v 博客前言

先交代下背景,寫這篇博客的緣由是一些經常使用的知識點得溫故而知新。第二個緣由是以前看過一些書,寫過一些代碼,可是沒有總結下來,下次再寫code的時候,發現有點茫然,因此決定將此知識點總結下來,方便之後查看。第三個緣由就是爲了經過寫博客,來保持長期學習的過程,天天打開博客園,發現上面發表博客的人,孜孜不倦地在學習,本身的心中固然有落差,爲何別人那麼牛,因此我得抓緊時間學習,看書,總結。面試

v寫在前面

若是您對如下的可能面試問到的題有所疑惑或不知道這些知識點,請繼續往下看,若是對您有所幫助,請點個贊;若是您對這些可能問到的知識點都成竹在胸,也請指點一二。編程

v正文開始

面試常見題:

1.委託是什麼?★☆設計模式

2.爲何須要委託?★☆安全

3.委託能用來作什麼?★☆多線程

4.如何自定義委託★☆閉包

5..NET默認的委託類型有哪幾種?★☆函數

6.怎樣使用委託?★★★post

7.多播委託是什麼?★★★學習

8什麼是泛型委託?★★★

9.什麼是匿名方法?★★

10.委託是否能夠回調實例方法★★★

11.Lambda表達式是什麼?

12.Lambda表達式怎麼傳參?★★★

13.Lambda多行代碼怎麼寫?★★

14.什麼是閉包?★★

事件的面試題我放在下一篇裏面。

看完這些題目,心中是否有疑惑呢?那就接着看唄,我來幫您解答心中的疑惑o(^▽^)o

參考答案:

1.委託是什麼?★☆

本題主要考察委託的概念:委託是尋址的.NET版本。在C++中,函數指針只不過是一個指向內存位置的指針,它不是類型安全的。咱們沒法判斷這個指針實際指向什麼,像參數和返回類型等項久更無從知曉了。而.NET委託徹底不一樣,委託是類型安全的類,它定義了返回類型和參數的類型。委託類不只包含對方法的引用,也能夠包含對多個方法的引用。

2.爲何須要委託?★☆

本題主要考察直接調用一個方法和經過委託來間接調用委託的區別。

在不少場景下直接調用方法是比較簡單方便的,可是在某些場景下,使用委託來調用方法能達到減小代碼量,實現某種功能的用途,好比說事件。

3.委託能用來作什麼?★☆

本題主要考察委託在咱們寫code時的用途。一個籠統的準則:當要把方法傳給其餘方法時,須要使用委託。好比下面幾個場景:

  a.啓動線程和任務

    調用System.Threading.Thread的一個實例上使用方法Start(),必須爲計算機提供開始啓動的方法的襲擊,

    即Thread類的構造函數必須帶有一個參數,該參數定義線程調用的方法。

    Thread t = new Thread(new ThreadStart(Go));//public static GO(){}

    有興趣的同窗能夠看下我以前寫的多線程的博客:乾貨分享:詳解線程的開始和建立

  b.設計模式中的簡單工廠模式。

    向一個方法中傳遞一個子類的方法。

  c.事件。

    通常通知代碼發生了什麼事件。GUI編程主要處理事件。在引起事件時,運行庫須要知道應執行哪一個方法。

    這就須要處理事件的方法做爲一個參數傳遞給委託。

4.如何自定義委託★☆

聲明一個委託類型,它的實例引用一個方法,該方法獲取一個int參數,返回void

public delegate void Feedback(int num);

理解委託的一個要點是它們的安全性很是高。在定義委託時,必須給出它所表示的方法的簽名和返回類型等所有細節。

理解委託的一種比較好的方式是把委託看成這樣一件事情:它給方法的簽名和返回類型指定名稱。

其語法相似於方法的定義,須要在定義方法的前面加上delegate關鍵字。定義委託基本上就是定義一個新的類,

因此能夠在任何地方定義類的相同地方定義委託,也就是說,能夠在另外一個類的內部定義,也能夠在任何類的外部定義,

還能夠在名稱控件中把委託定義爲定義爲頂層對象。訪問修飾符能夠是public/private/protected

5..NET默認的委託類型有哪幾種?★★

1.Action<T>

  泛型Action<T>委託表示引用一個void返回類型的方法。這個委託類存在16種重載方法。

  例如Action<in T1,In T2>調用沒有參數的方法

2.Func<T>

  Func<T>調用帶返回類型的方法。有16種重載方法。

  例如Func<out TResult>委託類型能夠調用帶返回類型且無參數的方法,

  Func<in T,out TResult>委託類型調用帶有4個參數和一個返回類型的方法。

3.等等

6.怎樣使用委託★★

下面我將會用個例子來說述怎樣使用委託

 1 // 聲明一個委託類型,它的實例引用一個方法,該方法獲取一個int參數,返回string
 2     public delegate String myMethodDelegate(int myInt);
 3     // 定義一些方法給委託變量引用
 4     public class mySampleClass
 5     {
 6         // 定義一個實例方法
 7         public String myStringMethod(int myInt)
 8         {
 9             if (myInt > 0)
10                 return ("positive");
11             if (myInt < 0)
12                 return ("negative");
13             return ("zero");
14         }
15         // 定義一個靜態方法
16         public static String mySignMethod(int myInt)
17         {
18             if (myInt > 0)
19                 return ("+");
20             if (myInt < 0)
21                 return ("-");
22             return ("");
23         }
24     }
25     public static void Main()
26     {
27         // 給每一個方法都建立一個委託實例
28         // 對於實例方法,mySC必須提供
29         //   對於靜態方法,只須要指定類的名字
30         mySampleClass mySC = new mySampleClass();
31         myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
32         myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);
33         // 調用委託
34         Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 5, myD1(5), myD2(5));
35         Console.WriteLine("{0} is {1}; use the sign \"{2}\".", -3, myD1(-3), myD2(-3));
36         Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 0, myD1(0), myD2(0));
37     }

輸出

5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".

7.多播委託是什麼?★★★

      包含多個方法的委託叫作多播委託。若是調用多播委託,就能夠順序連續調用多個方法。

  爲此,委託的簽名就必須返回void;不然,就只能獲得委託調用的最後一個方法的結果。

例子:

 1         /// <summary>
 2         /// 定義委託類型
 3         /// </summary>
 4         /// <param name="num"></param>
 5         /// <returns>void</returns>
 6         public delegate void Feedback(int num);
 7          
 8         /// <summary>
 9         /// 實例方法
10         /// </summary>
11         /// <param name="b"></param>
12         /// <returns>void</returns>
13         public void InstanceMethod(int a)
14         {
15             Console.WriteLine(a.ToString());
16         }
17         /// <summary>
18         /// 靜態方法
19         /// </summary>
20         /// <param name="a"></param>
21         /// <returns>返回void</returns>
22         public static void StaticMethod( int b)
23         {
24             Console.WriteLine((b * b).ToString());
25         }
26          
27         //定義一個Program實例
28         Program p = new Program();
29         //委託feedback1指定回調方法:p.InstanceMethod
30         Feedback feedback1 = new Feedback(p.InstanceMethod);
31         //委託feedback2指定回調方法:StaticMethod
32         Feedback feedback2 = new Feedback(StaticMethod);
33         //輸出2
34         feedback1(2);
35         //輸出4
36         feedback2(2);
37          
38         //----多播委託-------
39         Feedback fbChain = null;
40         //將feedback1添加到fbChain委託中
41         fbChain += feedback1;
42         //將feedback2添加到fbChain委託中
43         fbChain += feedback2;
44         //輸出:
45         //2
46         //4
47         fbChain(2);

8.什麼是泛型委託?★★★

     好比第5題提到的,Action<T>就是泛型委託。

注意事項:

  1.建議儘可能使用這些委託類型,而不是在代碼中定義更多的委託類型。這樣能夠減小系統中的類型數目,同時簡化編碼

  2.若是須要使用refout關鍵字,以傳引用的方式傳遞一個參數,就可能不得不定義本身的委託:

    delegate void Test(ref int i)

 

  3.若是委託要經過C#params關鍵字獲取可變數量的額參數,要爲委託的任何桉樹指定默認值,

    或者要對委託的泛型類型參數進行約束,也必須定義本身的委託類型

    delegate void EventHandler<TEventArgs>(Object sender, TEventArgs e)
        where TEventArgs : EventArgs;

 

  4.使用獲取泛型實參和返回值的委託時,可利用逆變與協變。逆變:父類轉換爲子類;協變:子類轉換爲父類

9.什麼事匿名方法★★

匿名方法是用做委託的參數的一段代碼。

 1         //匿名方法,例1
 2         Func<int, int> anon = delegate(int i)
 3         {
 4             i = i+1;
 5             return i;
 6         };
 7         //輸出2
 8         Console.WriteLine(anon(1));
 9          
10         //匿名方法,例2
11         Action<int> anon2 = delegate(int i)
12         {
13             i = i + 1;
14         };
15         //輸出2
16         Console.WriteLine(anon(1));

10.委託是否能夠回調實例方法★★★

能夠。委託能夠回調實例方法和靜態方法。若是是實例方法,委託須要知道方法操做的是哪一個對象實例。

11.Lambda表達式是什麼?

C#3.0開始,就可使用一種新語法把實現代碼賦予委託:Lambda表達式。

只要有委託參數類型的地方,就可使用Lambda表達式。

12.Lambda表達式怎麼傳參?★★★

Lambda表達式有幾種定義參數的方式。

1.只有一個參數,只寫出參數名就足夠了。

以下面的例子:

定義了一個泛型委託,輸入參數是一個string類型,返回一個string類型,

lambda表達式:s=>s.Replace('a,b')

委託引用的方法名:oneParam

傳入參數:abc

打印結果:bbc

1 Func<string, string> oneParam = s => s.Replace('a', 'b');
2 Console.WriteLine(oneParam("abc"));
3 Console.ReadKey();

2.若是委託使用多個參數,就把參數名放在小括號中。

以下面的例子:

定義了一個泛型委託,輸入參數是兩個int類型(能夠給小括號中的變量名添加參數類型),返回一個int類型,

lambda表達式:(i, j) => i*j

委託引用的方法名:twoParam

傳入參數:24

打印結果:8

1 Func<int, int, int> twoParam = (i, j) => i*j;
2 Console.WriteLine(twoParam(2,4));

13.Lambda多行代碼怎麼寫?★★

添加大括號,若是須要返回值,則必須添加return語句

1 Func<int, int, int> test = (i, j) => 
2 { 
3     i = i + 1;
4     i = i * j;
5     return i;
6 };
7 Console.WriteLine(test(2, 4));

打印結果:12

14.什麼是閉包?★★

經過Lambda表達式能夠訪問Lambda表達式塊外部的變量,這成爲閉包。

當引用外部變量時,須要注意,外部變量變化時,lambda表達式的結果也可能會隨着外部變量變化而變化。

以下面的例子:

1 int y = 5;
2 Func<int, int> lambda = x => x + y;
3 Console.WriteLine(lambda(1));
4 y = 10;
5 Console.WriteLine(lambda(1));

第一次打印出6,第二次打印出11

 

v寫在最後

關於委託的知識點還有不少沒有總結出來,好比說委託和反射,委託的底層實現等等。面試常常會問到也就是上面總結的。後續還會總結更多關於.NET的知識點。但願獲得園友們的支持!


做  者: Jackson0714
出  處:http://www.cnblogs.com/jackson0714/
關於做者:專一於微軟平臺的項目開發。若有問題或建議,請多多賜教!
版權聲明:本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
特此聲明:全部評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信
聲援博主:若是您以爲文章對您有幫助,能夠點擊文章右下角推薦一下。您的鼓勵是做者堅持原創和持續寫做的最大動力!

相關文章
相關標籤/搜索