我们在讲委托的时候讲到了多播委托,而多播委托是事件实现的基础,也就是说事件是用多播委托实现的。而事件是一个委托对象。
在开发基于对象的应用程序时,需要使用一种对象通信方式,在一个对象里面发生了其他对象感兴趣的事情,就需要通知其他对象发生了什么,并让其做出反应,这就需要用到事件,可以把事件看成是对象之间的通信的一个媒介。
那么委托就是对对象与对象之间通信的媒介,也就是事件的封装方式。
在事件中有两个对象,一个是监听对象,另一个就是监听者。
例如:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { public class Heater//监听对象 { private int temperature;//其他对象感兴趣的(字段)。即监听者感兴趣的对象。 public delegate void BoilHandler(int param); //声明委托 public event BoilHandler BoilEvent; //声明事件,用委托对事件进行封装。 public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature >= 96)//事件触发的条件即temperature>=96时事件被触发 { if (BoilEvent != null)//判断是否有方法注册 { BoilEvent(temperature);//如果有方法注册到委托链,当事件被触发的时候则调用委托链上的方法。 } } } } } public class Display//监听者1 { public static void Show(int a) { Console.WriteLine("水烧开了,水的温度为:{0}",a); } } public class Alert//监听者2 { public void Warn(int b) { Console.WriteLine("滴滴滴滴滴滴!温度为{0}",b); } } class Program { static void Main(string[] args) { Heater heater= new Heater(); Alert alert = new Alert(); heater.BoilEvent += Display.Show;//注册方法,Display的静态方法的注册 heater.BoilEvent += alert.Warn;//注册方法 heater.BoilWater(); Console.ReadKey(); } } }
运行结果:
由上面的运行结果可以看出方法调用的顺序就是我们在注册方法的顺序,可以得出,事件是由多播委托实现的。
我们改变一下注册的顺序看一下运行结果:
即:
Heater heater= new Heater(); Alert alert = new Alert(); heater.BoilEvent += alert.Warn;//注册方法 heater.BoilEvent += Display.Show;//注册方法,Display的静态方法的注册 heater.BoilWater(); Console.ReadKey();
改变注册顺序之后我们可以看出方法的调用顺序就随之改变。更能验证事件的基础其实就是多播委托。
由上面的例子可以看出,其实事件就是一个多播委托,只不过这个委托有些特殊,只有满足条件的时候才会被调用,而这个满足条件据就会触发事件。
还有就是事件的注册其实就是多播委托方法的注册。事件触发的时候,所调用的就是多播委托注册的方法。而且调用方法的顺序与我们注册方法的顺序相同,这就与多播委托的机制不谋而合。
由此可以看出:事件就是 一个特殊的委托对象。