一、委托的概念
-
委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。
-
借用百度上的一句话概括:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,
可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
二、委托的声明
与对应的方法具有相同的参数类型、参数个数、返回值。通俗来讲就是“函数的模板原型”。
三、委托的使用
- 用delegate声明一个委托
- 委托实例化
- 调用
public class DelegateClass { public delegate void DelegateTest(int a, int b); //1、声明一个委托 public static void Test() { DelegateTest method = new DelegateTest(Plus); //2、实例化委托 //DelegateTest method1 = Plus; //实例化委托的另一种等价写法 method.Invoke(1, 2); //3、调用 //method1(3, 4); //调用的另一种等价写法 } private static void Plus(int a, int b) { Console.WriteLine("a={0} b={1}", a, b); } }
四、委托的意义
1、没有委托就没有异步
2、解耦
3、高效扩展
public class CallStudent { //方法1 public static void CallStudentA(string name) { Console.WriteLine("{0}", name); } //方法2 public static void CallStudentB(string name) { Console.WriteLine("{0}", name); } //方法3 public static void CallStudentC(string name) { Console.WriteLine("{0}", name); } //传值的方式,根据值来决定行为,所有的方法全部耦合在一起, //如果要增加方法则需要修改该方法,不便于方法的封装、扩展 public static void CallStudentName(string name, StudentType type) { if (type == StudentType.A) { Console.WriteLine("{0}", name); } else if (type == StudentType.B) { Console.WriteLine("{0}", name); } else if (type == StudentType.C) { Console.WriteLine("{0}", name); } } //用委托的方式来实现传递方法,如果要增加方法,只需要重新增加一个方法就好 public static void CallStudentName(string name, CallStudentHandler handler) { handler.Invoke(name); } } public delegate void CallStudentHandler(string name); public enum StudentType { A, B, C }
static void Main(string[] args) { //用不同的值来区分不同的方法 CallStudent.CallStudentName("Student A",StudentType.A ); CallStudent.CallStudentName("Student B", StudentType.B); CallStudent.CallStudentName("Student C", StudentType.C ); Console.WriteLine(); //用委托的方式传递多个方法 CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA); CallStudent.CallStudentName("Student A", handlerA); CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB); CallStudent.CallStudentName("Student B", handlerB); CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC); CallStudent.CallStudentName("Student C", handlerC); Console.WriteLine(); //用匿名函数的方法替代上述写法 CallStudentHandler handler1 = new CallStudentHandler( delegate(string name) { Console.WriteLine("{0}", name); }); //用匿名的方式把方法名给去掉 handler1.Invoke("Student A"); //用lambda表达式的方式1 替代上述写法 //Lambda表达式的本质就是一个匿名方法 CallStudentHandler handler2= new CallStudentHandler( (string name)=> { Console.WriteLine("{0}", name); }); //用lambda表达式的方式把delegate换成=> 箭头左边是参数列表,右边是方法体 handler2.Invoke("Student A"); //用lambda表达式的方式2 CallStudentHandler handler3 = new CallStudentHandler( (name) => { Console.WriteLine("{0}", name); }); //去掉参数类型 handler3.Invoke("Student A"); //用lambda表达式的方式3 CallStudentHandler handler4 =(name) => { Console.WriteLine("{0}", name); }; //去掉 new CallStudentHandler handler4.Invoke("Student A"); //用lambda表达式的方式4 CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name); //去掉{},适用于方法体只有一行 //去掉{}后,如果方法体只有一行,带返回值的去掉return handler5.Invoke("Student A"); Console.ReadLine(); }