委托提供与C++中“函数指针”相同的功能,用于传递和调用函数的引用,是观察者模式的一种实现。
事件是用委托实现的,是对委托的额外封装,其本质上是一种特殊的委托。
事件是基于委托的,为委托提供了一个发布/订阅机制。可以说事件是一种特殊的委托,他的调用和委托是一样的。
事件的作用
- 封装订阅: 事件将委托的订阅操作进行封装,仅允许 += 和 -= 操作,避免程序员在开发时因误用 = 使得委托链断裂
- 封装发布: 事件确保只有包含它类才能触发事件通知,杜绝在委托中出现的“订阅者”也能触发
委托实例的调用可以在声明委托的类的内部和外部调用(不安全)。
事件对象的调用只能在声明事件的类的内部调用(安全)。(事件和委托的使用代码几乎完全相同)
事件的声明
public event 委托类型 事件名称
通常事件的命名以事件名称+Event来命名。如public event delegate NotifyEvent;
事件和委托的区别如下:
事件只能在方法的外部进行声明,而委在方法的外部和内部都可以声明。
事件只能在类的内部触发,不能在类的外部触发。而委托在类的内部和外都都可以触发。
委托一般用于回调,而事件用于外部接口。例如在观察者模式中,在被观察者中可以声明一个事件作为外部观察者注册的接口。
同时,这个事件只能在被观察者内部触发,而观察者中无法触发该事件,从而保证了安全性。
本篇使用分别使用委托和事件来实现简单的观察者模式例子,三个版本输出完全相同,为方便对比,使用了最原始的delegate语法。读者可以对比三版的不同之处来了解两者的区别。
委托版本
using System;
namespace LearningDelegate
{
class Program
{
static void Main(string[] args)
{
//出版社有一本叫《故事会》的杂志
Publisher publisher = new Publisher("《故事会》");
//读者小A订了这本杂志
Observer observerA = new Observer("小A");
publisher.Magazine +=