为什么MSDN建议在委托声明中包含对象发件人?

我正在阅读这个页面,我注意到它是如何说这是标准的指导方针:

.NET Framework指南指出,用于事件的委托类型应该带有两个参数,一个指示事件源的“对象源”参数和一个封装关于该事件的附加信息的“e”参数。

我可以理解在某些情况下如何让object sender有用,但我可以在其他人看到相反的情况。 例如,

  • 如果一个处理事件的班级不应该知道是谁开了这个事件? 耦合,凝聚力,以及所有这些。

  • 在我的情况下,我已经将对象引用为成员变量。 我就是这样认同这个事件的。 只会有它的一个实例,所以没有理由抛出发送者对象而不是仅仅使用成员变量。

  • 在我的程序中,发送者对象不应该被客户知道。 这很难解释我在做什么,但基本上我有一个内部构造函数的类内的库,该库也由该库中的两个其他类使用。 我的客户端类正在订阅来自这两个类的事件,但事件最初是从这个客户端不应该知道的内部类中调用的。

  • 这让事件处理程序的客户感到困惑。 图书馆应该很容易理解,在我的情况下,没有理由使用发件人变量。 没有。 那为什么要包括它?

  • 话虽如此,微软为什么要表明事件处理程序应该遵循这些准则? 这不是总是最好的选择吗?

    编辑:感谢大家的回复。 我决定和大多数人一起使用EventHandler<T>来处理这个库中的所有事件。


    我认为这种模式的原因是为了强化一些一致性。 sender参数允许为多个发布者(按钮,表)重新使用单个处理程序。

    为了解决您的观点:

    1)根本不使用它。 这是常见的,并不会真正伤害任何良好做法。

    2)没关系,再次忽略发件人

    3)与你在2)中所说的完全矛盾...
    其余部分与1)相同。 你甚至可以考虑将null作为发送者。

    4)“为什么要包含它” - 还有其他用例需要发件人。


    但请注意,这只是图书馆向BCL确认的指南。
    你的情况听起来更像是一个特定的应用程序(不是库),所以可以随意使用你喜欢的任何参数方案。 编译器不会抱怨。


    你正在反抗风,.NET框架有一定的设计,规则和指导方针,当使用它时,如果你想正确使用它,你应该遵循这些方向。

    如果您使用原始委托,则您拥有所需的所有自由,但如上所述,如果您为事件声明委托类型,则还应包括sender对象和EventArgs对象(基类或派生类)。

    如果你违反了这些规则,正如我刚才在回答你的其他问题时所说的那样:我应该使用EventArgs还是简单的数据类型?,最终可能会导致代码中断。

    当框架调用控件上的OnClick事件时,最大限度地简化.NET框架确实传递发件人和EventArgs实例......如果事件不符合,则某些事件可能会中断。

    如果你想完全自由,那么使用简单的代表而不是事件。


    首先,重要的是要注意指南不是法律。

    如果你不遵守指导方针,所有地狱(或程序员相当于)都不会失败。

    因此,请随意更改适当的事件签名。

    然而,知道为什么要添加这些指导原则同样重要,并且该问题答案的一大部分是版本控制。

    通过具有以下两部分,并且只有这两部分:

  • 事件的来源,尽可能地键入“通用”(请注意,事件签名是在系统中引入适当的泛型之前设计的,因此object与后来的泛型一样)
  • 一个从EventArgs继承的对象
  • 那么你正在设计更适应变化的代码。

    首先,由于您没有“允许”添加或删除参数,所有未来版本的活动仍然只有sendere

    其次,关于e参数的指南还有第二部分。 如果您在类库的新版本中决定通过更改e参数的类型来更改事件处理函数的签名,则应该通过从当前类型降序并传递后代来使其更具体。

    原因是已经处理您当前(旧)类型的现有代码仍然有效。

    因此,指南背后的全部理由是:

  • 保持一致(如其他人所述)
  • 面向未来的设计(通过确保在您发布X + 1版本时针对您的类的X版编写的代码仍然有效,而无需手动更改该代码)
  • 现在,如果这不是您的情况,请随时不要遵循指南。

    事实上,你可以从一个Action创建一个事件,它会工作得很好。

    链接地址: http://www.djcxy.com/p/55049.html

    上一篇: Why does MSDN recommend including object sender in delegate declarations?

    下一篇: Django Performance Tuning Tips?