前面一章学习了委托以及多播委托,接下来咱们来学习下委托事件。学习
在学习委托事件的前提下,得知道什么是观察者模式。spa
首先,咱们来模拟一个场景:例如,当一只狗汪汪汪叫的时候,baby被吓哭了,恰好要偷东西的小偷被吓跑了。code
咱们一惯的思惟是:建立三个类,分别写一个方法表示他们的动做,当狗叫的时候,分别调用。代码以下:blog
public class Dog { public static void Wang() { Console.WriteLine("狗汪汪汪汪"); Baby.Cry(); Thief.Run(); } } public class Baby { public static void Cry() { Console.WriteLine("baby被吓哭了"); } } public class Thief { public static void Run() { Console.WriteLine("小偷跑了"); } } class Program { static void Main(string[] args) { Dog.Wang(); Console.Read(); } }
这样作是能够获得咱们想要的结果,可是,Dog类与Baby、Thief之间的耦合就很紧了,不利于后期维护扩展。当咱们后期需求变更,要再添加一个动做:猫也被吓的跑掉了。事件
怎么办,难道咱们还要去改动Dog类里Wang方法的代码嘛?这明显是一个糟糕的事情。不过老是有办法解决的,毕竟办法都是人想出来的。string
上一个章节咱们知道了多播委托,就是把多个方法绑定到同一个委托,而后依次执行。it
接下来咱们来看看怎么实现。event
一、首先咱们得声明一个委托,而且建立这个委托的实例。class
二、当狗叫的时候,咱们来调用这个委托。扩展
三、当咱们调用狗叫以前,将要触发的一系列动做(也就是观察者的动做)绑定到委托就好了。
这3个步骤的代码以下:
public delegate void DogWang(); public class Dog { static DogWang DogWangHandler; public static void Wang() { Console.WriteLine("狗汪汪汪汪"); if (DogWangHandler != null) DogWangHandler.Invoke(); } } class Program { static void Main(string[] args) { Dog.DogWangHandler = new DogWang(Baby.Cry); Dog.DogWangHandler += Thief.Run; Dog.Wang(); Console.Read(); } }
贴一下结果吧。
没毛病。讲到这里,恍然大悟了,这样的话,咱们后需求添加多少个动做都不要紧,咱们只须要将方法绑定(+=)给委托就行。固然也是能够取消(-=)某一个动做的。
接下来咱们就要开始讲事件了,
那么什么是事件呢?什么是委托呢,它们以前又是什么关系呢?我想这个问题确定有不少人想知道,也有不少人搞不清楚。
咱们知道委托是一种类型,而事件就是委托一个实例 。其实就是这么简单的。
咱们将上面的代码用事件来实现,看看是什么样的。
public delegate void DogWang(); public class Dog { public static DogWang DogWangHandler; public static event DogWang DogWangHandlerEvent;//事件的本质就是委托的一个实例。加了event关键字 public static void Wang() { Console.WriteLine("狗汪汪汪汪"); if (DogWangHandlerEvent != null) DogWangHandlerEvent.Invoke(); } } class Program { static void Main(string[] args) { Console.WriteLine("==============事件实现================"); Dog.DogWangHandlerEvent += Baby.Cry; Dog.DogWangHandlerEvent += Thief.Run; Dog.Wang(); Console.Read(); } }
结果以下:
结果和上面同样,这是就委托事件。那么委托与事件调用有什么不同呢?
一、事件不能像委托同样 Dog.DogWangHandler = new DogWang(Baby.Cry); 被这样初始化。由于委托能够 Dog.DogWangHandler = null; ,用事件是为了避免能在外部随随便便地将委托给 null 。
二、事件不能像委托同样在外部调用 Dog.DogWangHandler(); ,这样是为了调用者不能想调用就调用。为了防止当触发一个件事,执行到一部分的时候就来调用。
小结一下:其实它们以前的区别就是一个权限问题。