委托 你怎么看?


一 前言

  對於委托給自己的感覺一直都是,知其然,而不知其所以然,而對於程序員來說,對於自己不是很了解的領域總是缺少安全感,為了有安全感於是我定好好理解一翻,

以下是自己的一點總結,如有不對,還請在評論中指出,謝謝。

 

二 自定義委托

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"

 

五 總結

    當寫完這篇文章時,對委托的理解有了一個較為全面的了解,掃去了自己的又一個盲區,成長的過程是緩慢的,關鍵在於堅持。

 

    如果您覺得本文有給您帶來一點收獲,不妨點個推薦,為我的付出支持一下,謝謝~

    如果希望在技術的道路上能有更多的朋友,那就關注下我吧,讓我們一起在技術的路上奔跑

 

成長在於積累


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM