浅谈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

 

posted @ 2018-11-07 15:03  KingFuture  阅读(4288)  评论(0编辑  收藏  举报