《C#从现象到本质》读书笔记(六)第二部分 C#特性 第8章委托和事件
从这一部分开始,知识点就相对少了,重要的是代码练习。奈何太高深的代码平常不怎么用,这些特性也不是经常写代码的。
委托是事件的基础。
委托不是类型的成员之一,但事件是。委托是一个密封类,可以看成是一个函数指针,它可以随情况变化为相同签名的不同函数。
方法的签名必须和委托一致,方法签名包括参数的个数、类型和顺序;方法的返回类型要和委托一致,注意,方法的返回类型不属于方法签名的一部分。
使用委托分为三步:1)定义委托。2)创建委托的一个实例,并指向一个合格的方法(其输入、输出和委托本身相同)。3)同步或异步调用方法。
委托有三大作用:代码复用、异步调用和作为回调(即事件的基础)。
1 public enum Operator 2 { 3 Add,Subtract,Multiply,Divide 4 } 5 6 class Program 7 { 8 public delegate double CalculateDelegate(double a, double b);//1.定义 9 static void Main(string[] args) 10 { 11 double a = 1; 12 double b = 2; 13 Console.WriteLine("Result:{0}",Calculate(a,b,Add));//3.调用 14 Console.ReadKey(); 15 } 16 17 public static double Calculate(double a, double b, CalculateDelegate cd) 18 { 19 //2.指向 20 return cd.Invoke(a, b); 21 } 22 public static double Calculate(double a, double b, Operator o) 23 { 24 switch (o) 25 { 26 case Operator.Add: 27 return Add(a, b); 28 case Operator.Subtract: 29 return Subtract(a, b); 30 case Operator.Multiply: 31 return Multiply(a, b); 32 case Operator.Divide: 33 return Divide(a, b); 34 default: 35 return 0; 36 } 37 } 38 39 public static double Add(double a, double b) 40 { 41 return a + b; 42 } 43 public static double Subtract(double a, double b) 44 { 45 return a - b; 46 } 47 public static double Multiply(double a, double b) 48 { 49 return a * b; 50 } 51 public static double Divide(double a, double b) 52 { 53 if(b==0) throw new DivideByZeroException(); 54 return a / b; 55 } 56 }
方法本身也可以看成是一种特殊类型的变量。
协变和逆变都是针对引用类型的。
Invoke方法赋予其同步访问的能力,BeginInvoke、EndInvoke赋予其异步访问的能力。
委托时类型安全的。
如果委托链中含有很多委托,只会收到最后一个含有返回值的委托的返回值。假如这个委托方法是由输出值的,而且想令委托链上的下一个方法的输入等于上一个方法的输出值,只能通过GetInvocationList方法得到委托链上的所有方法,然后一一执行。
事件必须包括三部分:
1)事件的订阅者(subscriber)。2)事件的触发者,或者发布者(publisher)。
3)订阅者和触发者之间的数据传送通道。
使用事件的步骤需要:
1)声明一个事件处理方法,指出事件发生时订阅者应该有怎样的反应。
2)声明委托。委托的签名和事件的处理方法相同。
3)声明基于该委托的事件。
4)为事件增加订阅者。
5)在事件符合条件时,调用事件。
之后会慢慢补充这部分用到的一些代码。