为什么使用事件来代表我可以做什么呢?

我知道事件总是与代表联系在一起。 但是,我错过了一些事件的核心用法,并试图理解这一点。

我创建了一个简单的事件程序,如下所示,它工作得很好。

namespace CompleteRef3._0 { delegate void someEventDelegate(); class EventTester { public event someEventDelegate someEvent; public void doEvent() { if (someEvent != null) someEvent(); } } class Program { static void EventHandler1() { Console.WriteLine("Event handler 1 called.."); } static void EventHandler2() { Console.WriteLine("Event handler 2 called.."); } static void EventHandler3() { Console.WriteLine("Event handler 3 called.."); } static void Main(string[] args) { EventTester evt = new EventTester(); evt.someEvent += EventHandler1; evt.someEvent += EventHandler2; evt.someEvent += EventHandler3; evt.doEvent(); Console.ReadKey(); } } } 

我用委托替换了事件声明。 那就是我替换了行公共事件someEventDelegate someEvent;someEventDelegate someEvent; 在上面的程序中,我仍然得到相同的结果。 现在,我很困惑为什么我们需要使用事件,如果它只能由Delegates实现。 事件的真正用途是什么?

没有事件的修改程序如下 –

 namespace CompleteRef3._0 { delegate void someEventDelegate(); class EventTester { someEventDelegate someEvent; public void doEvent() { if (someEvent != null) someEvent(); } } class Program { static void EventHandler1() { Console.WriteLine("Event handler 1 called.."); } static void EventHandler2() { Console.WriteLine("Event handler 2 called.."); } static void EventHandler3() { Console.WriteLine("Event handler 3 called.."); } static void Main(string[] args) { EventTester evt = new EventTester(); evt.someEvent += EventHandler1; evt.someEvent += EventHandler2; evt.someEvent += EventHandler3; evt.doEvent(); Console.ReadKey(); } } } 

当然,您可以使用委托,因为在幕后,事件是包装委托的构造。

但是使用事件而不是委托的基本原理与使用属性而不是字段相同 – 数据封装 。 直接暴露字段(无论它们是什么 – 原始字段或委托)是不好的做法。

顺便说一句,您在委托字段之前错过了一个public关键字,以便在第二个代码段中实现。

另一个“顺便说一句”与第二个片段:对于代表,你应该使用Delegate.Combine而不是“+ =”。

事件的主要目的是防止订户相互干扰。 如果您不使用活动,您可以:

通过重新分配委托(而不是使用+ =运算符)替换其他订户,清除所有订户(通过将委托设置为null),通过调用委托向其他订户广播。

来源:C#in a Nutshell

想象一下,你有3个订阅者对你的someEvent感兴趣。 他们订阅了这样的:

客户1

 EventTester evt = new EventTester(); evt.someEvent += Client1Handler1; evt.someEvent += Cleint1Handler2; 

客户2

 EventTester evt = new EventTester(); evt.someEvent += Client2Handler1; evt.someEvent += Client2Handler2; 

客户3

 EventTester evt = new EventTester(); evt.someEvent += Client2Handler1; evt.someEvent += Client2Handler2; 

现在想象另一个客户端这样做:

 EventTester = null; 

客户端1,2和3将不会收到任何事件,因为您有这行代码:

 if (someEvent != null) someEvent(); 

上面的代码行没有任何问题,但是使用委托有问题。

阿列克谢指出的另一个问题是:

 someEvent = new someEventDelegate(EventHandler2) 

如果您有一个event并且其中一个客户端尝试了上述操作,则不会允许它们出现编译错误,如下所示:

在此处输入图像描述