14 C# 第十三章 事件和委托(一) 多播委托的问题
来源:互联网 发布:淘宝天猫买药可靠吗 编辑:程序博客网 时间:2024/05/21 23:33
一个简单的概述
这里有一个小小的例子描述了一些单独使用委托链的局限。
知道了使事件的优势,用委托链的不足,也就更清楚了使用这样便于在设计时灵活的选择。
多播委托(委托链)
一个简单的实例:(cooler and heater)
程序中有两个工作实体, Cooler 和 Heater,它们会根据输入的温度改变自己的状态(On 或 Off) 有一个管理者Thermostat,Cooler 和 Heater会注册到它的委托链上。Main直接操纵Thermostat,把温度的输入给它,Thermostat会根据委托链上的委托进行操作。
这个小程序的主要目的是为了解释委托在使用时的不足之处。尤其通过时序图可以看的更加的清楚。
时序图:最有趣的是红色方框部分,当改变温度时委托链中的委托会被顺序的访问。
注意红色方框的部分, 有下面几个问题是值得考虑的:
1) 委托链中的异常
这是能想到的最直接的问题。委托链中的委托是被顺序访问的,当其中一个出现了异常,就会打破这个链。例如上面的委托链中 heater 先被访问,然后是cooler。可能cooler是我们需要处理温度变化的对象,但在委托链在访问 heater时出了异常,cooler就无法再执行了,虽然cooler可能一点问题都没有,但它没办法执行。
2) 委托链中的返回值
假设程序需要扩展一下,在第11步和第13步需要返回值给控制端,当控制端收到第11步的返回值后,委托链并没有终止,而是继续了13步,这样最终的返回值将总是第13步的返回值。3) 委托运算符,关于 “+=” 和 "-=" 操作
+=: 可以像委托队列中增加一个委托,它会取得委托链中的第一个委托,然后向后加入新的委托。在其内部使用的是System.Delegate.Combine()方法.
-+: 会从委托链中删除一个委托,但其实质并不是从委托链中删除一委托,使委托链比原来的少一个,而是建了一个新的委托链,这个新的委托链的基础是把原来的委托链减去目标的委托。其调用的是 System.Delegate.Remove() 方法。这里加了个MSDN的连接。
4) 委托空值的检查
无论是System.Delegate.Combine()还是System.Delegate.Remove()都是允许对空值操作的,在使用委托链时最好也判断一下。
实例程序:(对应上面的时序图)
using System;using System.Collections.Generic;using System.Text;namespace delegate_bad_point{ class Cooler { private float m_fTemperature; public Cooler(float fTemperature) { m_fTemperature = fTemperature; } public float Temperature { get { return m_fTemperature; } set { m_fTemperature = value;} } public void OnTemperatureChaged(float fNewTemperature) { if (fNewTemperature > m_fTemperature) { Console.WriteLine("Cooler : ON"); } else { Console.WriteLine("Cooler : OFF"); } } } class Heater { private float m_fTemperature; public Heater(float fTemperature) { m_fTemperature = fTemperature; } public float Temperature { get { return m_fTemperature; } set { m_fTemperature = value; } } public void OnTemperatureChaged(float fNewTemperature) { if (fNewTemperature < m_fTemperature) { Console.WriteLine("Heater : ON"); } else { Console.WriteLine("Heater : OFF"); } } } public class Thermostat { public delegate void TemperatureChangedHandler(float newTemperature); private TemperatureChangedHandler m_OnTemperatureChange; private float m_fCurrentTemperature; public TemperatureChangedHandler OnTemperatureChanged { get { return m_OnTemperatureChange; } set { m_OnTemperatureChange = value; } } public float CurrentTemperature { get { return m_fCurrentTemperature; } set { if (m_fCurrentTemperature != value) { m_fCurrentTemperature = value; TemperatureChangedHandler localOnChange = m_OnTemperatureChange; // check the null value, it's important if (localOnChange != null) localOnChange(value); } } } } class Program { static void Main(string[] args) { Cooler cool = new Cooler(80); Heater heat = new Heater(60); Thermostat thermostat = new Thermostat(); string strTemp = ""; thermostat.OnTemperatureChanged += heat.OnTemperatureChaged; thermostat.OnTemperatureChanged += cool.OnTemperatureChaged; Console.WriteLine("Enter temperature: "); strTemp = Console.ReadLine(); thermostat.CurrentTemperature = float.Parse(strTemp); Console.ReadKey(); } }}
下面将会使用事件方式来解决委托链中的问题。
- 14 C# 第十三章 事件和委托(一) 多播委托的问题
- c# 委托和多播委托
- 15 C# 第十三章 事件和委托(二) 使用事件
- c# 委托和委托事件
- C# 多播委托
- C#多播委托
- c#的委托和事件
- c#的委托和事件
- c#的委托和事件
- 多播委托与事件的案例
- c# 多播委托 和匿名方法
- 委托 创建 调用 多播委托 事件 委托与事件的区别
- C#事件-事件本身就是一种多播委托
- 关于C#多播委托的若干问题
- C# 中的委托和事件(一)
- C#中的委托和事件(一)
- C#中的委托和事件(一)
- C# 中的委托和事件(一)
- spring自定义标签
- 关键字static
- 第一学 Linux下的软件安装
- 程序人生之我们的故事:十年如歌(2)
- GPS 真实数据
- 14 C# 第十三章 事件和委托(一) 多播委托的问题
- 实验7
- MyEclipse&Eclipse 默认工作区设置
- oracle 中 dual 详解
- 小瓜牛漫谈 — String
- android.view.WindowManager$BadTokenException: Unable to add window异常
- JAVA的MAP的使用
- 关于“IT学子成长指导”专栏及文章目录
- StringBuffer和StringBuilder