重温面向对象核心 下 : 你一定能看懂的委托和事件
程序员文章站
2023-12-03 15:32:22
实例解读面向对象核心,所有例子基于 C#,涉及我们实务中最常关心的问题: 1、封装、继承、多态; 2、抽象类、接口; 3、委托、事件。 三、委托和事件 通俗的说,我们使用委托的目的是“实现将方法作为参数传递的效果”,直接结合例子说明。 我们还是用基于上次的示例往下更改。 场景设定:根据图形的不同,返 ......
实例解读面向对象核心,所有例子基于 c#,涉及我们实务中最常关心的问题:
1、封装、继承、多态;
2、抽象类、接口;
3、委托、事件。
三、委托和事件
通俗的说,我们使用委托的目的是“实现将方法作为参数传递的效果”,直接结合例子说明。
我们还是用基于上次的示例往下更改。
场景设定:根据图形的不同,返回不同的面积算法。
// 参数为图形形状, 返回该图形的面积计算公式 public string getareaalg(string shapename) { if (shapename=="矩形") { return "长 × 宽"; } else if (shapename == "圆形") { return "pi * r * r"; } else { return "该图形面积算法未定义"; } }
当图形越来越多时,方法体中的分支就会膨胀。
这时候我们很自然的想到,如果我们可以直接将方法作为参数传进来,那么就可以不需要这些分支了。
类似如下:
public string getareaalg(某种类型 计算面积公式的方法) { 执行此 计算面积公式的方法; }
好了,我们顺着这个思路改造一下:
#region delegate相关演示 //声明一个委托 public delegate string getareaalgdelegate(); // 矩形的面积算法 public string getrectangleareaalgorithm() { return "矩形的面积算法:长 × 宽"; } // 圆形的面积算法 public string getrcircleareaalgorithm() { return "圆形面积公式:pi * r * r"; } public string getareaalg(getareaalgdelegate getalgorithm) { return getalgorithm(); } #endregion
这个时候,在home/index中直接调用即可:
string stralgorith = getareaalg(getrectangleareaalgorithm);
加个断点调试一下,可以看到返回了 矩形的面积算法:长 × 宽
理解了吗?我们来小结一下。
委托是对函数的封装,可以当作给方法的特征指定一个名称,我们可以和普通的参数做类比来理解。
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用分支语句,同时使得程序具有更好的可扩展性。
接下来再谈下事件。
事件是委托的一种特殊形式,当事件发生时,事件对象通知处理过程。
我们改造下我们的例子,加一句就行,紧接着声明委托下面声明事件:
//声明一个委托 public delegate string getareaalgdelegate(); // 声明一个事件 public event getareaalgdelegate getarea;
同样在home/index中,调用时先登记事件:
getarea += new getareaalgdelegate(getrcircleareaalgorithm); string res= getarea();
加个断点调试一下,可以看见返回了 圆形面积公式:pi * r * r
我们通过实例化委托,将getrcircleareaalgorithm方法登记到事件 getarea 中,理解了吗?
我们按一下鼠标按钮,触发某个操作,执行某个方法就是典型的应用。
委托和事件实际上是观察者模式的应用。
具体的应用场景我就不展开了,大家可以思考。
仅以两张图片说明一个例子,启发大家思考。
观察者模式结构:
观察者模式例子:
祝学习进步。