EventArgs类背后的基本原理

ark*_*ark 10 .net c# events

我正在学习C#中的事件,并了解EventArgs该类包含有关该事件的数据.但我很难理解为什么EventArgs有必要.

例如,在这个MSDN示例中,WakeMeUp该类是否无法从字段中读取所有必要的数据(snoozePressed,nrings)AlarmClock?如果它可以设置它们,为什么它也不能得到它们?

Fre*_*örk 11

EventArgs类的好处(我认为)主要是这两个:

  • 您可以在不更改事件签名的情况下将成员添加到EventArgs类
  • 您从对象实例断开传递给事件处理程序的信息

甚至可能是EventArgs中包含的信息不会被引发事件的对象暴露.

当然,在某些情况下,它似乎有点矫枉过正,但我​​认为同样的力量在这里是一件好事; 如果你知道一个事件是如何工作的,你就会知道其他事件是如何工作的.


Mik*_*e J 9

EventArgs班是必要的,因为如果你想扩展您的活动,以在未来提供更多的信息,你就必须使用原始事件的原始方法签名的所有客户机的可移植性问题.

例如,

public void IHandleEventVersion1(string p1, int p2)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

现在,您希望在EventVersion1上面的事件中提供更多信息(您希望包含a char).然后,您必须强制客户端重写其事件处理以匹配您的新要求,如下所示:

public void IHandleEventVersion1(string p1, int p2, char p2)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

看看在尝试提供更多信息时它会变得多么尴尬?

因此,EventArgs该类提供了一个通用的设计模式来编程,允许您和我快速扩展我们想要为事件提供的数据.

事件框架的一般编码模式是这样的:

基本事件处理策略

  1. 定义event您的类的消费者可以订阅
  2. 定义delegate事件声明的签名(是的,您也可以使用.NET 2.0通用版本EventHandler,即EventHandler<TEventArgs>)
  3. protected virtual为继承者提供一种方法来覆盖,以响应在基类中引发的事件
  4. 在声明事件的基类中,提供protected实际引发事件的方法的基本实现.

    public class MyClass
    {
        public event EventHandler  /* (point 2) */ MyEvent; /* (point 1) */
    
        // (point 3 + 4)
        protected virtual void OnMyEvent()
        {
            EventHandler temp = MyEvent;
            if (temp != null)
                temp(this, EventArgs.Empty);
        }
    
        public void SomeMethodThatWillRaiseTheEvent()
        {
            ....
            OnMyEvent();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


Rob*_*Rob 6

EventArgs对以下内容非常有用:

  • 显示你的状态在时间点在事件发生的时间
  • 通过提供有关事件的信息来提高事件处理代码的性能,而无需查询"第三方"
  • 包含引发事件的对象未公开的数据

为了扩展第一点......在你被调用的事件处理程序和你从引发事件的对象中读取状态之间,其他事情可能已经发生,它将状态完全改变为其他东西.在这种情况下,您将响应警报已关闭的AlarmClock上的"AlarmHasGoneOff"事件.

它也可以响应"其他地方"引发的事件 - 通过各种不同的机制在另一台机器上的另一个进程/ appdomain /进程中响应.如果你不得不回到那个"其他地方"来获取你需要的信息,这可能需要几秒钟(或更少,或更多!),通过EventArgs或派生类传递有用/必需的数据是一个巨大的性能改进.