为什么C#中的事件应采用(发送者,EventArgs)?
众所周知,我们应该声明以参数(事件发送者,EventArgs args)为参数的事件。为什么?
解决方案
这使消耗者的开发人员能够为多个事件编写单个事件处理程序,而不管发送者或者事件如何。
编辑:我们为什么需要其他样式?我们可以继承EventArgs来提供任意数量的数据,更改模式只会使任何不得不使用这种新模式的开发人员感到困惑和沮丧。
因为这是任何回调机制的好模式,无论使用哪种语言。我们想知道谁发送了事件(发送者)和与事件相关的数据(EventArgs)。
似乎这是Microsoft随着时间的推移改进事件模型的方式。似乎他们也允许使用"新的" Action委托及其变体执行另一种方式。
这是一个很好的使用模式,无论执行什么事件,都可以找到发送该事件的内容。
最好覆盖EventArgs并通过它们传递数据也是最好的方法。 EventArgs是基类。如果我们查看调用事件的各种控件,则它们会覆盖EventArgs,从而为我们提供有关事件的更多信息。
即使我们不需要参数来执行事件,如果我们不将其包含在框架的第一次运行中并想在以后添加它们,我们也会破坏所有以前的实现,并不得不重新编写它们。另外,如果我们创建一个框架并进行分发,那么情况会变得更糟,因为使用该框架的每个人都需要重构。
实际上,无论这是否是进行事件的最佳实践方式,这都是有争议的。有一种流派认为,由于事件旨在分离两段代码,因此事件处理程序会获得发送方,并且必须知道将发送方转换为何种类型以便对其执行任何操作,这一事实是一种反图案。
对于事件传递的数据,使用单个参数EventArgs允许我们在将来的软件版本中将数据添加到事件中,而不会破坏现有的使用者。我们只需将新成员添加到现有EventArgs派生的类中,或者使用新成员创建派生类。
否则,使用EventArgs传递数据的一致性和最小惊讶原则是合理的。
对于发件人,在某些(但不是全部)情况下,了解发送事件的类型很有用。对于sender参数,使用object以外的其他类型过于严格:这意味着其他发送者无法重用相同的事件签名。
克里斯·安德森(Chris Anderson)在《框架设计指南》一书中说:
[T]his is just about a pattern. By having event arguments packaged in a class you get better versioning semantics. By having a common pattern (sender, e) it is easily learned as the signature for all events.
在某些情况下,涉及互操作的情况可能需要偏离此模式。
有时,我们想强制所有事件使用者使用特定的事件参数,例如,传递布尔值的安全事件,true为好,false为坏。
在这种情况下,我们希望消费者痛苦地意识到新参数,即,我们希望消费者与该参数结合在一起。请注意,消费者仍与事件触发类脱钩,但与事件未脱钩。
我怀疑这种情况适用于大量情况,在这些情况下,EventArgs的值会大大降低。