我对C#并不陌生,但事件是我在语言中遇到的最令人困惑的话题之一。 其中一个问题是:我应该在哪里将事件处理程序分配给事件,或者以其他形式分配问题:为什么在订阅者构造函数中引发了大多数事件?这是什么意思?
就像这个例子(摘自Mastering Visual C#一书)
public ReactorMonitor(Reactor myReactor)
{
myReactor.OnMeltdown +=
new Reactor.MeltdownHandler(DisplayMessage);
}
答案 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;
我们通常使用该语法,因为可能有多个处理程序订阅了一个事件。 +=
具有将我们的处理程序附加到列表的效果。您可以使用=
代替,但它会取消订阅任何现有的处理程序。
回答你的问题 - 你应该什么时候订阅活动?这是一个非常广泛的问题,但通常是
Init
活动期间订阅。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 按钮单击,或者它可以由其他程序逻辑引发,例如 改变财产的价值。