一 前言
對於委托給自己的感覺一直都是,知其然,而不知其所以然,而對於程序員來說,對於自己不是很了解的領域總是缺少安全感,為了有安全感於是我定好好理解一翻,
以下是自己的一點總結,如有不對,還請在評論中指出,謝謝。
二 自定義委托
2.1 什么是委托
委托和類一樣是一種用戶自定義的類型,但類表示的是數據的集合,而委托保存是的一個或多個方法 (精簡版)。
我覺得委托像是一個快遞公司,我們只要把包裹給它,它就會幫我們送到指定的地方。而委托就是把方法賦值給它,然后在指定的地方調用委托就行了。
2.2 委托常規操作
對於委托的一些常規操作就不多寫了,比較簡單就 一代(一段代碼)而過了。
1 //以下代碼包括了,聲明,創建,調用 委托,為委托增加方法 ,移除方法 2 3 //聲明委托 4 public delegate string MyDel(string name); 5 6 static void Main(string[] args) 7 { 8 //創建委托對象, 並給委托對象賦值 9 MyDel dele = Print;//將方法賦給委托時只需要傳遞方法名即可 10 //給委托增加方法,也可以這么寫 11 //MyDel dele1 = Print; 12 //MyDel dele2 = Write; 13 //MyDel dele3 = dele1 + dele2; 14 dele += Write; 15 //給委托移除方法 16 dele -= Write; 17 //調用委托 18 dele("Zery"); 19 } 20 21 private static string Print(string name) 22 { 23 return name; 24 } 25 26 private static string Write(string name) 27 { 28 return name; 29 }
2.3 匿名方法
2.2中的代碼賦給委托的方法都是 “具名方法”,可以重復使用的,如果賦給委托的方法只需要調用一次呢?定一個方法是不是太浪費了呢,
那匿名方法就出場了,什么是匿名方法我就不解釋了,看名字就知道了。寫一寫使匿名方法的注意點:
1 必須要有 delegate類型關鍵字,
2 必須要與委托的參數返回值匹配
好了上代碼
//聲明委托 public delegate int DelegateDemos(int x); // 把匿名方法賦給委托,參數,與返回值都必須一樣,還要有delegate關鍵字 DelegateDemos dele3 = delegate(int x) { return x + 20; }; //調用委托 dele3(20)//返回40
有了匿名方法后是不是感覺方便清爽很多呢 不用再去定義一個方法了少了很多代碼。
那 delegate(int x) { return x + 20; }; 這段代碼能否再簡化一點呢,那是肯定的 這個時候就要引入 "Lambda"表達示了 “=>”
有了lambda表達示后可以將匿名方法轉換為lambda表達示寫法
1 DelegateDemos dele3 = delegate(int x) { return x + 20; };//匿名方法 2 DelegateDemos dele4 = (int x) => { return x + 20; };//lambda表達示 3 //編譯器還可以從委托的 中聲明中知道委托參數的類型因此可以省略參數類型 4 DelegateDemos dele4 = (x) => { return x + 20; }; 5 //如果只有一個隱式類型參數,我們可以省略周圍的圓括號 6 DelegateDemos dele4 = x => { return x + 20; }; 7 //lambda表達式表達式的主體是語句塊或表達式,如果語句塊包含了一個返回語句 8 //可以將語句塊,替換為return關鍵字后的表達式 9 DelegateDemos dele4 = x => x + 20;
關於Lambda表達 式的參數列表的要點如下
1 lambda表達式的參數列表 中的參數必須在參數數量,類型和位置上與委托 相匹配。
2 表達 式的參數列表中的參數不一定需要包含類型(比如隱式類型),除非委托 有ref 或out 參數這時類型是必須的
3 如果只有一個參數,並且是隱式類型的周圍的圓括號就可以省略,否則就是必須的
4 如果沒有參數,必須使用一組空括號
三 .net Freamwork定義的委托
3.1 Action泛型委托
Action是沒有返回值的泛型委托,可以有0-16個參數
1 internal class ActionDelegate 2 { 3 public void ActionMethod(int x) 4 { 5 Console.WriteLine(x + 20); 6 } 7 } 8 9 ActionDelegate actionDelegate = new ActionDelegate(); 10 //接收0-16個參數 沒有返回值 11 Action<int> action = actionDelegate.ActionMethod; 12 //綁定多個方法時要用 “+=” 13 action += x => Console.WriteLine(x + 20);//匿名方法 14 //調用時只要調用一次即可,會按綁定順序來執行綁定的方法 15 action(30);
3.2 Func 委托
可以有0-16個參數,但是返回類型是必須要的 如0個參數的Func委托 :Func<TResult> func 這里的TResult指得就是返回類型
1 internal class FuncDelegate 2 { 3 public int FuncMethod(int x) 4 { 5 Console.WriteLine(x); 6 return x; 7 } 8 } 9 FuncDelegate funcDelegate = new FuncDelegate(); 10 11 //接收0-16個參數 最后一個參數為返回值 12 Func<int, int> func = funcDelegate.FuncMethod; 13 14 func += x => x + 20; //匿名方法 15 16 int result =func(20);//接收返回值 17 Console.WriteLine(result);
3.3 Predicate委托
Predicate只有一個參數,且返回值為bool類型
1 internal class PredicateDelegate 2 { 3 public bool PredicateMethod(int x ) 4 { 5 return x > 50; 6 } 7 } 8 PredicateDelegate predicateDelegate = new PredicateDelegate(); 9 // 只有一個參數 並返回bool 值 10 Predicate<int> predicate = predicateDelegate.PredicateMethod; 11 12 predicate += x => x > 50; //匿名方法 13 14 bool results =predicate(60); 15 Console.WriteLine(results);
四 委托綜合應用
1 internal class PeopleInfo 2 { 3 public int Id { get; set; } 4 5 public string Name { get; set; } 6 7 public int Age { get; set; } 8 } 9 10 11 var peopleList = new List<PeopleInfo>(); 12 peopleList.Add(new PeopleInfo() { Id = 1, Name = "Zery", Age = 20 }); 13 peopleList.Add(new PeopleInfo() { Id = 2, Name = "Zhang", Age = 25 }); 14 /*==============Action 委托===================*/ 15 //自定義委托 16 peopleList.ForEach(delegate(PeopleInfo x) { Console.WriteLine("姓名:{0} 年齡:{1}", x.Name, x.Age); }); 17 18 //Action 委托 19 Action<PeopleInfo> action = x => Console.WriteLine("姓名:{0} 年齡:{1}", x.Name, x.Age); 20 peopleList.ForEach(action); 21 22 //Lambda表達示 23 peopleList.ForEach(o=> Console.WriteLine("姓名:{0} 年齡:{1}",o.Name,o.Age)); 24 25 //全部輸出: 姓名:Zery 年齡:20 26 // 姓名:Zhang 年齡:25 27 28 /*==============Func 委托=====================*/ 29 //自定義委托 30 var deleFValue = peopleList.Where(delegate(PeopleInfo x) { return x.Name == "Zery"; }); 31 Console.WriteLine(deleFValue.FirstOrDefault().Name); 32 33 //Func 委托 34 Func<PeopleInfo, bool> func = x => x.Name=="Zery"; 35 var funcFValue = peopleList.Where(func); 36 Console.WriteLine(funcFValue.FirstOrDefault().Name); 37 38 //Lambda表達示 39 var lamaFValue = peopleList.Where(o => o.Name == "Zery"); 40 Console.WriteLine(lamaFValue.FirstOrDefault().Name); 41 42 //全部輸出:"Zery" 43 44 45 /*==============Predicate 委托================*/ 46 //自定義委托 47 var delePValue = peopleList.Find(delegate(PeopleInfo x) { return x.Age == 25; }); 48 Console.WriteLine(delePValue.Name); 49 50 //Predicate 委托 51 Predicate<PeopleInfo> predicate = x => x.Age == 25; 52 var preValue = peopleList.Find(predicate); 53 Console.WriteLine(preValue.Name); 54 55 //Lambda表達示 56 var lamPValue = peopleList.Find(o=> o.Age==25); 57 Console.WriteLine(lamPValue.Name); 58 59 //全部輸出:"Zhang"
五 總結
當寫完這篇文章時,對委托的理解有了一個較為全面的了解,掃去了自己的又一個盲區,成長的過程是緩慢的,關鍵在於堅持。
如果您覺得本文有給您帶來一點收獲,不妨點個推薦,為我的付出支持一下,謝謝~
如果希望在技術的道路上能有更多的朋友,那就關注下我吧,讓我們一起在技術的路上奔跑
成長在於積累


