EventArgs作为事件模式中的基类的目的是什么?

Mas*_*aus 7 .net c# events eventargs

经典的一般C#事件具有以下参数:

(object sender, EventArgs e)
Run Code Online (Sandbox Code Playgroud)

我可以为e参数实现一个具有更具体签名的事件,派生EventArgs.

现在,基类的目的是什么EventArgs?我的意思是......它是空的.没有基础/抽象/虚拟属性,也没有字段或其他内容.

为什么基本事件的参数不像下面那样?

(object sender, object eventArgs)
Run Code Online (Sandbox Code Playgroud)

也就是说,为什么所有带有一些已实现和特定的event-args参数的事件都是EventArgs从一个简单的派生而不是从一个简单派生出来的object

上述问题与以下问题相对应.通用表单中的事件委托是:

delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)
Run Code Online (Sandbox Code Playgroud)

并且对参数没有限制e.但是我会期待类似的东西where TEventArgs : EventArgs,一致......

Mic*_*ick 6

对象不会排除像int,double等值类型.这将引入装箱和解拳问题.在对象上使用基类的选择是强制在整个API中传递强类型对象的选择.

当我看到对象类型的普遍使用时,我倾向于畏缩,因为它有点击败了使用强类型编程语言的全部观点,你可能会在javascript中编程,尽管任何熟悉javascript的人都会知道他们正在努力一个强类型的编程范式.

编辑: 进一步详细说明传递引用类型和值类型的事件模型之间的区别.当处理事件的代理人改变事件的数据时,许多人在提交事件时经常会这样做,如果传递的数据是值类型,那么您需要开始考虑是否要更改按值传递的副本或原始引用的值类型,当然你希望你改变原来的.在.NET事件模型中强制传递引用类型是一个非常关键的设计决策.

  • 也许如果泛型在 .NET 1.0 中出现而不是 EventArgs,他们可能会使用`where TEventArgs : class` (3认同)
  • 它曾经是“ TEventArgs:EventArgs”的地方,但是当他们意识到像OP那样没有太多实际意义时,他们消除了限制。最初的想法是使所有事件都继承EventArgs,以便您可以将多个不同类型的事件订阅到一个方法中,但实际上这从来都不是一个好主意,现在对于lambda的可用性毫无意义。对于超级性能敏感的事件,我使用了强类型的sender以及对args直接有意义的任何类型,因此触发该事件不需要创建寿命很短的args对象。 (2认同)