应该在哪里举办活动?

时间:2017-04-30 21:03:30

标签: c# events delegates

我对C#并不陌生,但事件是我在语言中遇到的最令人困惑的话题之一。 其中一个问题是:我应该在哪里将事件处理程序分配给事件,或者以其他形式分配问题:为什么在订阅者构造函数中引发了大多数事件?这是什么意思?

就像这个例子(摘自Mastering Visual C#一书)

public ReactorMonitor(Reactor myReactor)
{
myReactor.OnMeltdown +=
new Reactor.MeltdownHandler(DisplayMessage);
}

2 个答案:

答案 0 :(得分:3)

提升=生成。订阅者构造函数中不会引发事件。订户根本不提出事件。 事件源引发/生成事件,订阅者订阅接收处理

c#中的事件只不过是函数指针,即包含指向特定签名(通常为Action<object,EventArgs>)的函数的指针(或指针列表)的变量。或者用this MSDN article

的话来说
  

委托就像C ++函数指针,但是类型安全。

当您订阅某个活动时,您实际上是在说&#34;存储我的功能的地址。当X发生时,请调用它(以及存储其地址的任何其他功能)。&#34;

因此代码

myReactor.OnMeltdown += Meldownhandler;

可以读作

objectThatRaisesEvents.FunctionPointer = MyHandler;

请注意,MyHandler后面没有括号。如果MyHandler()表示您正在调用该函数,则表达式MyHandler()的值实际上是函数的返回值; MyHandler本身并不调用函数或返回其值,而是返回处理程序本身的地址。因此,上面的代码行采用MyHandler地址并将其存储在名为FunctionPointer的变量中。

当引发事件的对象调用FunctionPointer()时,它告诉c#获取存储在FunctionPointer中的函数的地址并调用它。  所以它实际上间接地调用了MyHandler()。因此,这两行完全相同:

objectThatRaisesEvents.FunctionPointer();
MyHandler();

另请注意您示例中的+=。在c#中相当于

objectThatRaisesEvents.FunctionPointer = 
objectThatRaisesEvents.FunctionPointer + MyHandler;

我们通常使用该语法,因为可能有多个处理程序订阅了一个事件。 +=具有将我们的处理程序附加到列表的效果。您可以使用=代替,但它会取消订阅任何现有的处理程序。

回答你的问题 - 你应该什么时候订阅活动?这是一个非常广泛的问题,但通常是

  • 在ASP.NET网页中,您在Init活动期间订阅。
  • 在Windows窗体中,您可以使用InitializeComponent方法订阅。

当然还有很多其他背景......最重要的是你应该在需要接收事件发生通知之前订阅。

答案 1 :(得分:0)

该事件是使用实现Observer设计模式的委托模型构建的.NET Framework的标准功能之一。

https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx

https://en.m.wikipedia.org/wiki/Observer_pattern

您订阅活动的位置取决于业务规则,但大多数时候您希望尽早订阅,这通常是对处理事件感兴趣的类的构造函数。

另一方面,当事件应该被提出时,取决于你试图与订阅者通信的内容,如果它是状态更改的通知,那么一旦状态发生变化就会引发事件。

  

事件是对象发送的消息,用于指示发生的事件   行动。该操作可能是由用户交互引起的,例如a   按钮单击,或者它可以由其他程序逻辑引发,例如   改变财产的价值。