为什么C#中的事件应该接受(发送方、事件参数)?

为什么C#中的事件应该接受(发送方、事件参数)?,c#,.net,events,C#,.net,Events,众所周知,您应该声明作为参数的事件(objectsender,EventArgs args)。为什么?这使消费型开发人员能够为多个事件编写单个事件处理程序,而不考虑发送方或事件 编辑:为什么需要不同的图案?您可以继承EventArgs以提供任意数量的数据,而更改模式只会让被迫使用此新模式的开发人员感到困惑和沮丧。因为它是任何回调机制的良好模式,无论使用何种语言。您想知道是谁发送了事件(发送者)以及与事件相关的数据(EventArgs)。这似乎是Microsoft随着时间的推移改进事件模型的方法。

众所周知,您应该声明作为参数的事件
(objectsender,EventArgs args)
。为什么?

这使消费型开发人员能够为多个事件编写单个事件处理程序,而不考虑发送方或事件


编辑:为什么需要不同的图案?您可以继承EventArgs以提供任意数量的数据,而更改模式只会让被迫使用此新模式的开发人员感到困惑和沮丧。

因为它是任何回调机制的良好模式,无论使用何种语言。您想知道是谁发送了事件(发送者)以及与事件相关的数据(EventArgs)。

这似乎是Microsoft随着时间的推移改进事件模型的方法。他们似乎还允许用另一种方式来实现“新”动作委托及其变体

这是一个很好的使用模式,这样,任何实现事件的人都可以找到发送它的内容

重写EventArg并通过它们传递数据也是最好的方法。EventArgs是一个基类。如果查看调用事件的各种控件,它们会覆盖EventArgs,从而提供有关事件的更多信息


即使您不需要参数来执行事件,但如果您在第一次运行框架时没有包含这些参数,并且希望在以后添加它们,那么您将破坏所有以前的实现,并且必须重新编写它们。另外,如果你正在创建一个框架并打算发布它,情况会变得更糟,因为每个使用你框架的人都需要重构。

实际上,这是否是进行活动的最佳实践方式,这是有争议的。有一种学派认为,由于事件旨在解耦两段代码,因此事件处理程序获取发送者,并且必须知道将发送者强制转换为什么类型才能对其执行任何操作,这是一种反模式。

使用单个参数EventArgs,因为事件传递的数据允许您在软件的未来版本中将数据添加到事件中,而不会中断现有使用者。您只需向现有EventArgs派生类添加新成员,或使用新成员创建派生类

否则,一致性和最少意外的原则证明可以使用EventArgs传递数据


至于发送方,在某些(但不是所有)情况下,了解发送事件的类型很有用。对发送方参数使用对象以外的类型限制太多:这意味着其他发送方无法重用相同的事件签名。

Chris Anderson在《框架设计指南》一书中说:

[T] 他的理论只是一种模式。通过将事件参数打包到类中,可以获得更好的版本控制语义。通过使用公共模式
(发送者,e)
,可以很容易地将其作为所有事件的签名


有些情况主要涉及互操作,需要偏离此模式。

有时,您希望强制所有事件使用者使用特定的事件参数,例如,传递布尔参数的安全事件,正确为true,错误为false。 在这种情况下,您希望您的消费者痛苦地意识到新参数,即您希望您的消费者与该参数耦合。请注意,您的使用者仍然与事件触发类解耦,但与事件无关


我怀疑这种情况适用于大量情况,在这些情况下,EventArgs的值会大大降低。

单独使用EventArgs类是无用的,因为它必须派生以实例化任何内容。这将表明应该使用一个子类,并且许多子类已经存在于.NET中。遗憾的是,我找不到任何好的通用的

假设您希望将日志记录委派给一个通用事件。。。无需编写自己的EventArgs子类。这似乎是一个毫无意义的练习,但我喜欢使用现有的功能。您可以通过Object参数传递字符串,但这违背了它的预期用途。试着在Google上找到EventArgs子类的一个很好的参考,你会发现没有任何问题。(至少我做到了。)

ReSharper有点帮助,因为当您键入“EventArgs”时,您将看到一个包含字符串“EventArgs”的所有类(在您的使用/导入范围内)的列表。仔细阅读该列表,您将看到许多没有字符串成员的类。当您访问ControlEventArgs时,您会看到文本属性可能会被使用,但会占用windows控件的所有开销ConvertEventArgs可能很有用,因为您将类型与数据一起传递,但这仍然需要紧密耦合,这种耦合既没有很好的文档记录,也没有本质上的类型安全性DataReceivedEventArgs没有实现EntryWriteEventTargets需要一个带有字节数组或数据流上下文的EventLogEntry<如果您不介意在内部调用所有日志事件Exception ErrorEvents,则strong>ErrorEventArgs更接近,并显示一条异常消息FileSystemEventArgs可能是迄今为止最接近的,有两个字符串和一个必需的WatcherChangeTypes枚举参数,如果您知道自己在做什么,可以将其设置为0LabeledEventTargets使用int和字符串,如果您不介意需要Windows.Forms命名空间的话RenamedEventArgs与FileSystemEventArgs类似,但有一个额外的字符串。最后,System.Runtime.InteropServices中的ResolveEventArgs传递一个字符串。还有其他库,但我坚持使用一些最常见的库。因此,根据实现的不同,我可以使用ErrorEventArgsFileSystemEventArgsResolveEventArgs进行日志记录。

“Object sender”允许在