繁体   English   中英

为什么*应该*我们使用EventHandler

[英]Why *should* we use EventHandler

我讨厌EventHandler。 我讨厌如果我想对sender做任何事情,就必须抛弃sender 我讨厌必须创建一个继承自EventArgs的新类才能使用EventHandler<T>

一直有人告诉我EventHandler是一种传统,等等……等等。 但是我找不到这个教条仍然存在的原因。

有一个原因为什么要创建一个新的代表是一个坏主意:

delegate void EventHandler<TSender, T>(TSender sender, T args);

这样, sender将是类型安全的,并且我可以将我想要的任何内容作为参数传递(如果需要,可以包括自定义EventArgs)。

如果您完全信任的代码将第三方代码托管为部分信任,则实际上有充分的理由要求第二个参数从EventArgs派生。

由于事件处理委托的回调是在引发代码而不是第三方代码的上下文中完成的,因此恶意第三方代码有可能将特权系统操作添加为事件处理程序,从而有可能执行升级通过在完全受信任的上下文中运行代码来进行特权攻击,以使其部分受信任的上下文无法运行。

例如,如果您将处理程序声明为YourEvent += Enviroment.Exit(-1) int -> void类型,则第三方代码可能使YourEvent += Enviroment.Exit(-1)排队,并让您无意退出该过程。 这显然会引起一个易于检测的问题,但是可能有更多的恶意API可能被排入队列以执行其他操作。

当签名为(object, EventArgs) -> void则框架中没有可排队的特权操作,因为它们均不与此签名兼容。 它是框架中安全代码检查的一部分,以确保做到这一点(不幸的是,我在阅读本文时无法找到源文件)。

因此,在某些情况下,对于为什么应使用标准模式存在有效的安全问题。 如果您100%确信在这种情况下将永远不会使用您的代码,那么事件签名指南就不那么重要了(除了其他开发人员认为WTF的情况除外),但是如果可以,那么您应该遵循它。

除了已接受的.net约定外 ,没有其他理由使用它,任何阅读您的代码的人都应该很容易理解它。 为此,这是一个很好的理由。

但是,这是您的代码,您可以决定最适合您的代码。 当然,当您与fcl进行交互时,您将必须使用事件处理程序来做到这一点。

我通常将Action<...>类型用作事件处理程序-如果您不需要与特别需要EventHandler其他代码(或设计器)进行互操作,则没有理由使用它。

好吧,执行所有此类转换是不寻常的,客户端代码通常已经知道发送方是谁,因为它仅为一个对象明确预订了该事件。 共享事件处理程序非常少见。 如果需要常见的行为,那么更好的方法是从类派生并重写OnXxxx方法。 然后,您可以不再计较发件人 ,你得到这个

但是,通过在自定义EventArgs派生类中包含对发件人的类型安全的引用,可以轻松解决问题。

我同意您的看法,惯例是愚蠢和/或过时的。 用正确的类型安全性和泛型以正确的方式进行操作。

它总是在您有任务要做的时候出现,您可以按照最后一个人做的方式来做,也可以按照您认为可能更好的另一种方式来做。

通常选择第一个选择-与最后一个选择相同,这样就不会遇到麻烦。 但是第二选择是从长远角度改进软件。 (或者至少可以改善它,如果您是对的,您的方法会更好!:))

正如Preet Sangha所说的那样,创建这样的委托不是一个好主意,这是因为其他开发人员可能会困惑您为什么要这样做。

使用EventHandler委托是此处提供的指南: http : //msdn.microsoft.com/zh-cn/library/ms229011.aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM