![](https://csdnimg.cn/release/download_crawler_static/86263294/bg5.jpg)
注意在 Register()方法中,我们使用了赋值操作符“=”,而非“+=”,通过这种方式
就避免了多个方法注册。上面的代码尽管可以完成我们的需要,但是此时大家还应该注意下
面两点:
1、将 NumberChanged 声明为委托变量还是事件都无所谓了,因为它是私有的,即便将
它声明为一个委托变量,客户端也看不到它,也就无法通过它来触发事件、调用订阅者的方
法。而只能通过 Register()和 UnRegister()方法来注册和取消注册,通过调用 DoSomething()
方法触发事件(而不是 NumberChanged 本身,这在前面已经讨论过了)。
2、我们还应该发现,这里采用的、对 NumberChanged 委托变量的访问模式和 C#中的属
性是多么类似啊?大家知道,在 C#中通常一个属性对应一个类型成员,而在类型的外部对
成员的操作全部通过属性来完成。尽管这里对委托变量的处理是类似的效果,但却使用了两
个方法来进行模拟,有没有办法像使用属性一样来完成上面的例子呢?答案是有的,C#中提
供了一种叫事件访问器(Event Accessor)的东西,它用来封装委托变量。如下面例子所示:
class Program {
static void Main(string[] args) {
Publishser pub = new Publishser();
Subscriber1 sub1 = new Subscriber1();
Subscriber2 sub2 = new Subscriber2();
pub.NumberChanged -= sub1.OnNumberChanged; // 不会有任何反应
pub.NumberChanged += sub2.OnNumberChanged; // 注册了 sub2
pub.NumberChanged += sub1.OnNumberChanged; // sub1 将 sub2
的覆盖掉了
pub.DoSomething(); // 触发事件
}
}
// 定义委托
public delegate string GeneralEventHandler();
// 定义事件发布者
public class Publishser {
// 声明一个委托变量
private GeneralEventHandler numberChanged;
// 事件访问器的定义
public event GeneralEventHandler NumberChanged {
add {
numberChanged = value;
}
remove {
numberChanged -= value;
}