1 什么是委托
·委托(delegate)是函数指针的“升级版”
·C#语言通过委托这种数据类型保留了与函数指针相对应的功能
·委托是函数指针的升级版,它可以按照一定的约束来指向某些目标方法,帮助我们完成对这些方法的间接调用
·一切皆地址
·变量(数据)是以某个地址为起点的一段内存中所存储的值
·函数(算法)是以某个地址为起点的一段内存中所存储的一组机器语言指令
·直接调用与间接调用
·直接调用:通过函数名来调用函数, CPU通过函数名直接获得函数所在地址并开始执行->返回
·间接调用:通过函数指针来调用函数,CPU通过读取函数指针存储的值获得函数所在地址并开始执行->返回
·Java中没有与委托相对应的功能实体
·委托的简单使用(C#中最常用的两个委托)
·Action委托(指向Report方法选用Action委托)
·Func委托(指向Add方法和Sub方法选用Func委托)
或者(仿照函数指针的调用方式)
2 委托的声明(自定义委托)
·委托是一种类(class),类是数据类型,所以委托也是一种数据类型
·它的声明方式与一般的类不同(委托的声明仿照函数指针的声明格式),主要是为了照顾可读性和C/C++传统
·声明委托的例子
·注意声明委托的位置
·委托是一种类,我们需要把它声明在名称空间内,这样它与其他的类就处于同一个级别
·避免写错地方结果声明成嵌套类型(C#允许在一个类里声明另一个类)
·委托与所封装的方法必需“类型兼容”
//第一行是委托类型的声明,下面四行是委托可以封装的方法
delegate double Calc(double x, double y);
double Add(double x, double y) { return x + y; }
double Sub(double x, double y) { return x - y; }
double Mul(double x, double y) { return x * y; }
double Div(double x, double y) { return x / y; }
·委托可以封装的方法在返回值类型上和参数列表的类型上必须与委托的返回值类型和参数列表类型保持“类型兼容”(即:返回值的数据类型一致、参数列表在个数和数据类型上一致(参数名不需要一样))
3 委托的使用
委托的一般使用
实例:把方法当作参数传给另一个方法
·正确使用1:模板方法,“借用”指定的外部方法来产生结果
·相当于“填空题”
·常位于代码中部
·委托有返回值
·这里使用模板方法的好处是:如果工厂想要生产更多种类的产品,在使用模板方法后,Product类、Box类和ProductFactory类都不需要再动,只需要不停扩展ProductFactory类中的内容即可。只要把方法封装到委托类型的对象中,传给模板方法,模板方法就可以给产品包装并且交还回来。这样就最大限度实现了代码的重复使用。
·正确使用2:回调(callback)方法,调用指定的外部方法
·相当于“流水线”
·常位于代码末尾
·委托无返回值
总结
无论是模板方法还是回调方法,他们的本质相同,都是用委托类型的参数封装一个外部的方法,然后将这个方法传进模板方法的内部,再进行间接调用。
委托的高级使用
·多播(multicast)委托
·多播委托指一个委托内部封装着不止一个方法
·单播委托
·多播委托
·两个的结果都如下图的所示:
·隐式异步调用
·同步调用与异步调用的对比
·间接同步调用
·结果
·使用委托进行隐式异步调用
·结果(分支线程和主线程独立执行,有可能会发生资源的争抢)
·显式异步调用
方式一:使用Thread进行显式的异步调用(结果:主线程和分支线程相互独立执行)
方式二:使用Task进行显式的异步调用(结果:主线程和分支线程相互独立执行)