淺談C#委托的用法-delegate


2018年11月7日     小雨

一、委托的概念

  1. 委托和類一樣是一種用戶自定義類型,它存儲的就是一系列具有相同簽名和返回類型的方法的地址,調用委托的時候,它所包含的所有方法都會被執行。

  2. 借用百度上的一句話概括:委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,

    可以避免在程序中大量使用If-Else(Switch)語句,同時使得程序具有更好的可擴展性

二、委托的聲明

  與對應的方法具有相同的參數類型、參數個數、返回值。通俗來講就是“函數的模板原型”。

三、委托的使用

  1. 用delegate聲明一個委托
  2. 委托實例化
  3. 調用
 1 public class DelegateClass
 2     {
 3         public delegate void DelegateTest(int a, int b);  //1、聲明一個委托
 4 
 5         public static void Test()
 6         {
 7             DelegateTest method = new DelegateTest(Plus);   //2、實例化委托
 8             //DelegateTest method1 = Plus;  //實例化委托的另一種等價寫法
 9             method.Invoke(1, 2);   //3、調用
10             //method1(3, 4);   //調用的另一種等價寫法
11         }
12 
13         private static void Plus(int a, int b)
14         {
15             Console.WriteLine("a={0} b={1}", a, b);
16         }
17     }
View Code

四、委托的意義

  1、沒有委托就沒有異步

  2、解耦

  3、高效擴展

 1 public class CallStudent
 2     {
 3         //方法1
 4         public static void CallStudentA(string name)
 5         {
 6             Console.WriteLine("{0}", name);
 7         }
 8         //方法2
 9         public static void CallStudentB(string name)
10         {
11             Console.WriteLine("{0}", name);
12         }
13         //方法3
14         public static void CallStudentC(string name)
15         {
16             Console.WriteLine("{0}", name);
17         }
18 
19         //傳值的方式,根據值來決定行為,所有的方法全部耦合在一起,
20         //如果要增加方法則需要修改該方法,不便於方法的封裝、擴展
21         public static void CallStudentName(string name, StudentType type)
22         {
23             if (type == StudentType.A)
24             {
25                 Console.WriteLine("{0}", name);
26             }
27             else if (type == StudentType.B)
28             {
29                 Console.WriteLine("{0}", name);
30             }
31             else if (type == StudentType.C)
32             {
33                 Console.WriteLine("{0}", name);
34             }
35         }
36 
37         //用委托的方式來實現傳遞方法,如果要增加方法,只需要重新增加一個方法就好
38         public static void CallStudentName(string name, CallStudentHandler handler)
39         {
40             handler.Invoke(name);
41         }
42     }
43 
44     public delegate void CallStudentHandler(string name);
45 
46     public enum StudentType
47     {
48         A,
49         B,
50         C
51     }
View Code

 

 1 static void Main(string[] args)
 2         {
 3             //用不同的值來區分不同的方法
 4             CallStudent.CallStudentName("Student A",StudentType.A );
 5             CallStudent.CallStudentName("Student B", StudentType.B);
 6             CallStudent.CallStudentName("Student C", StudentType.C );
 7             Console.WriteLine();
 8 
 9             //用委托的方式傳遞多個方法
10             CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA);
11             CallStudent.CallStudentName("Student A", handlerA);
12 
13             CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB);
14             CallStudent.CallStudentName("Student B", handlerB);
15 
16             CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC);
17             CallStudent.CallStudentName("Student C", handlerC);
18             Console.WriteLine();
19 
20             //用匿名函數的方法替代上述寫法
21             CallStudentHandler handler1 = new CallStudentHandler(
22                 delegate(string name)
23                 {
24                     Console.WriteLine("{0}", name);
25                 }); //用匿名的方式把方法名給去掉
26             handler1.Invoke("Student A");
27 
28             //用lambda表達式的方式1 替代上述寫法
29             //Lambda表達式的本質就是一個匿名方法
30             CallStudentHandler handler2= new CallStudentHandler(
31                 (string name)=>
32                 {
33                     Console.WriteLine("{0}", name);
34                 }); //用lambda表達式的方式把delegate換成=>  箭頭左邊是參數列表,右邊是方法體
35             handler2.Invoke("Student A");
36 
37             //用lambda表達式的方式2
38             CallStudentHandler handler3 = new CallStudentHandler(
39                 (name) =>
40                 {
41                     Console.WriteLine("{0}", name);
42                 }); //去掉參數類型
43             handler3.Invoke("Student A");
44 
45             //用lambda表達式的方式3
46             CallStudentHandler handler4 =(name) =>
47                 {
48                     Console.WriteLine("{0}", name);
49                 }; //去掉 new CallStudentHandler
50             handler4.Invoke("Student A");
51 
52             //用lambda表達式的方式4
53             CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name);   //去掉{},適用於方法體只有一行
54             //去掉{}后,如果方法體只有一行,帶返回值的去掉return
55             handler5.Invoke("Student A");
56 
57             Console.ReadLine();
58         }
View Code

 


免責聲明!

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



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