2017.11.06 委托

分享人:蔡永堅


1. 問題描述:委托。

功能要求:已知有一個字符串數組,將該數組里的長度為2字符串選出來;

沒學習委托時做法:寫一個方法,傳入一個字符串,然后遍歷判斷每個字符串的長度,將長度為2的字符串重新組成數組返回。

存在問題:當條件變換時(變成長度大于3),那么得重新寫一個方法。

使用委托:

List<string> strlist = new List<string>();

IEnumerable<string> newstrlist =strlist.Where(delegate(stringa)
 { return a.Length == 2; });

注:IEnumerable<T> 是一個接口, 他定義了一個可被枚舉對象

List < T > 是一個泛型集合類的實現, 他實現了上面的接口,

strlist.Where()是系統的方法,它的參數是一個委托:delegate(string a) { return a.Length == 2; }。

  • 什么是委托
  1. 從數據結構來講,委托是和類一樣是一種用戶自定義類型。

  2. 從設計模式來講,委托(類)提供了方法(對象)的抽象。

既然委托是一種類型,那么它存儲的是什么數據?

委托是方法的抽象,它存儲的就是一系列具有相同簽名和返回回類型的方法的地址。調用委托的時候,委托包含的所有方法將被執行。

  • 如何使用委托

在使用委托的時候,你可以像對待一個類一樣對待它。即先聲明,再實例化。只是有點不同,類在實例化之后叫對象或實例,但委托在實例化后仍叫委托。

  • 委托聲明:public delegate bool SelectStr (string a);

上述代碼指出,如果要創建SelectStr的一個實例,需要帶一個string 參數的方法,而且該方法需要有一個bool返回類型。

  • 定義一個方法:
public staticbool  Function(stringa)
 { return  a.Length == 2; }

  • 創建一個委托實例:SelectStr s = new SelectStr(Function);

創建委托實例,使用了new 關鍵字,說明委托也是類,將方法名Function作為參數綁定到該委托實例,也就是將方法Function指派給SelectStr委托,并將該引用賦給s對象,也就表示s對象保存了指向Function方法的引用,以此實現了對Function的回調。由此可見,委托表示了對其回調方法的簽名,可以將方法當做參數進行傳遞,并根據傳入的方法來動態的改變方法調用,只要為委托提供相同的簽名的方法,都可以與委托綁定。

  • 調用委托:bool a=s(“aa”);

可以認為該代碼結果等于bool a= Function(“aa”);

回到上訴的.where里的參數delegate(string a) { return a.Length == 2;}。這個其實是委托的匿名函數。


2. 泛型委托:

private Func<string, bool> del;
del =new Func<string, bool>(Function);

上面泛型委托定義和下面委托的定義得到的del結果相同。

public delegate bool SelectStr (string a);
SelectStr 
del = new SelectStr (Function);

為什么系統會提供泛型委托,可以這么理解:我們在開發中會將一個類多次實例化,而并不是每次要用到同一個類都去創建類再實例化。使用普通的委托定義其實是每次定義一個委托,再實例化,可以理解成每次要用到同一個類都去創建類再實例化相似,因此出現泛型委托,其中泛型委托有兩種:Func和Action.他們的區別在于Func是有返回值的,它的最后一個參數類型就是方法返回類型,前面的參數類型是方法的參數類型(要一一對應),而Action沒有返回值,因此他不需要最后多一個參數。


3. 委托加減運算:

可以使用+=運算符,為委托新增方法。

同樣可以使用-=運算符,為委托移除方法。

del += ClassName.FunctionName; // 增加方法
del -= ClassName. FunctionName; //移除

當一個委托通過+=新增多個方法時,調用該委托會將新增的所有方法執行一遍,如果該委托是有返回值的,那么它只返回最后一次增加的方法的返回值。


4、Lambda表達式

Lambda表達式主要用來簡化匿名方法的語法。在匿名方法中,delegate關鍵字有點多余,因為編譯器已經知道我們將方法賦值給委托。通過幾個簡單步驟,我們就可以將匿名方法轉換為Lambda表達式:

在參數列表和匿名方法主體之間防Lambda運算符=>。Lambda運算符讀作"goes to"。

private Func<string, string> del;
del = delegate( string x) { returnx; };//匿名方法
del = (string x) => {return x;};//Lambda表達式
del = x => {return x};//簡寫的Lambda表達式


5. 推薦一個學習網站:傳智播客

http://www.itcast.cn/

里面有很多免費的開發教程視頻,講得很詳細,有時間可以去學學。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容