【C#学习】--委托
.1 委托
.1.1 概述
委托(代理)关键字delegate,是一种程序特性,它是用来代表方法、表示方法的,用编程里的另一个说法:委托是方法的指针。
我们首先看看通常的声明语法:
int age = 10; //这里整型变量age代表的是10这个整型值
Course myCourse = new Course();//这里将Course类实例化出一个myCourse对象,myCourse是一个特定对象的代表
而委托的声明语法在格式上与上面没有什么差别:
delegate 委托变量名 = 具体方法;//但只是格式上没啥差别,本质上委托和上面的两种声明有很大的区别(见下面)
.1.2 诞生意义及应用场景
结合实际联想:一件事情我们自己处理不了,可以委托别人来帮助处理
我 (委托)别人 做某事
delegate 委托变量名 = 具体方法;//是不是对应上了?需要注意!这里的具体方法可以是一个也可以是多个
前面的age、myCourse代表的都是某种“静态数据”,而委托代表的是一种“动态数据(行为数据)”,而这个行为就是方法(最开始学习编程的时候我们就知道,方法代表我们需要系统运行的动作)
在软件开发中,我们也会面临类似情况,一个方法因为已经在一个特定对象中被调用,此时我们想用另一种对象去调用这个方法时往往无法直接调用,这时候就可以使用委托解决。
情境举例:
如何达成我们上面用B在A中实例化的对象b在A中成功调用A的方法呢(这里与方法是否公有无关)?
使用委托。
.1.3 委托的使用
委托的基本使用
第一步,声明委托(方法的原型——方法的返回值类型、方法的参数列表)
第二步,根据委托编写具体方法
第三步,创建委托变量(委托是引用类型)
第四步,将委托变量和一个或多个符合委托定义的方法关联(这里就就又一次体现了委托变量和以前学过的其他变量的区别,比如上面的int类型变量age同一时间只能和一个值关联,但委托可以同时关联多个方法)
第五步,通过委托变量使用关联的具体方法
运行结果:
由此可见,通过委托变量,我们可以轻松地调用委托所关联的所有具体方法
如果我们给委托变量关联了多个方法,当我们使用委托变量的时候,方法会按照关联的顺序依次被调用执行,这种委托使用称为“多路委托”或“多播委托”
既然我们能动态地关联新方法到同一个委托,是否能动态地移除已经被关联到委托的方法呢?
答案是肯定的!使用跟+=相反的-=运算即可
移除了方法2前后的运行结果:
上面我们以void返回值无参方法为例,那么对于有特定返回值类型和参数列表的方法使用委托有什么注意的呢?
声明委托时,需要保证委托的参数列表中的变量个数和变量类型保持一致,变量名无需一致
我们同样声明三个同参数列表同返回值的方法,并将他们依次关联到同一委托中
这里有一个问题,我们关联了三个方法,却只给了一组同时符合三个方法的实参,那委托是否会对这组实参依次调用这三个方法?
很显然没有,对于这种情况,委托只运行一次截至当前所关联的最新方法。
委托的实战应用(一) 多窗体通信
功能(一) 子窗体发送信息,主窗体接收信息
这里的情境:在主窗体A中,创建了若干子窗体B的对象,现在需要在B窗体中调用窗体A中功能为接收信息的方法。
正常情况下无法调用,但可以通过委托实现。
委托变量和具体方法的关联,通常是分开的,一般是在声明具体方法的地方进行关联。
既然是主窗口中的方法,先在主窗口中声明即将用于存储方法的委托(理论上可以在声明具体方法后、后续通过委托调用此具体方法前声明委托,但正常的逻辑步骤是我们在声明方法前就应该根据后续是否需要通过委托调用该方法来首先声明委托,然后再声明具体方法,这里遵循上面提到的委托的基本使用逻辑顺序)
再声明主窗口中的具体方法(这里是接收信息的方法)
然后在子窗口中声明即将用于存储上面主窗口中方法的委托变量
这里注意声明委托变量遵循的规范:在哪里使用,就在哪里声明。
显而易见,我们使用委托变量在子窗口中调用关联到该委托变量中的主窗口接收信息的方法,所以我们在子窗口中声明委托变量
然后我们在主窗口中将接收信息的具体方法关联到刚刚在子窗口中声明的委托变量
最后我们在子窗口中通过委托变量(此时该委托变量仅关联了一个发送信息的具体方法)实现主窗口接收子窗口信息的功能
运行结果:
通过断点调试,可以检查是否通过子窗体中的委托变量成功调用关联到该委托变量中的主窗体中的具体方法
成功跳转到主窗体中的具体方法
成功运行:
功能(二) 主窗体消息广播
这次我们在子窗体中声明一个显示传入信息的方法(后面我们只需要将主窗体广播文本框内的内容作为参数传入这个方法即可),因此这个方法应该是在主窗体中使用委托实现调用
所以首先需要在主窗体中声明一个委托用于关联子窗体中的这个方法
然后按照上面的思路依照刚刚声明的委托规范在子窗体中声明具体方法
在主窗体中声明委托变量,并将子窗体中的方法关联到该委托变量
最后在主窗体的“广播”按钮点击事件中使用关联了接收信息方法后的委托
运行结果:
扩展:关闭所有子窗口
将所有子窗口作为元素存入集合,再遍历集合内的每个元素执行关闭窗口的命令
委托的实战应用(二) 解决在容器嵌入窗体时的切换问题(思考)