C#类订阅自己发布的事件是不是很糟糕?

var*_*ian 11 c# events

我可能只是神经质,但我经常发现自己处于发布事件的类的情况下,我觉得从类本身(例如在构造函数中)订阅此事件很方便,而不仅仅是从外部课程订阅.

这对我来说听起来很合理,但我无法忍受这种拙劣的做法,因为我总是面临这样一个问题:"为什么不执行你在事件处理程序中提供的动作在触发事件的代码中?"

public class Button
{
   public Button()
   {
      this.Click += someHandler; // bad practice?
   }

   public event EventHandler Click;

   public void HandleInput()
   {
      if (someInputCondition)
      {
         // Perform necessary actions here rather than 
         // subscribing in the constructor?
         this.Click(this, ...);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

订阅自己的活动有什么缺点吗?

Eri*_*ert 8

这对我来说听起来很合理,但我无法忍受这种拙劣的做法,因为我总是面临这样一个问题:"为什么不执行你在事件处理程序中提供的动作在触发事件的代码中?"

要回答这个问题,请考虑部分类场景.假设您有一个基本类型B.您运行一个自动化工具,通过将其扩展到派生类D来装饰B.您的工具生成一个部分类,以便使用D的开发人员可以进一步自定义它以用于自己的目的.

在这种情况下,当D的机器生成的一方提出由B或D的机器生成的一侧引发的事件时,D的用户创作的一方想要注册被调用似乎是完全合理的.

这是我们多年前设计VSTO时遇到的情景.事实证明,在C#中执行此操作并不困难,但要让它在VB中运行起来非常棘手.我相信VB已经对他们的事件订阅模型做了一些调整,以使这更容易.

那说:如果你能避免这种情况,我愿意.如果您只是为内部订阅制作一个看似糟糕的代码味道的事件.C#3中的部分方法在这里有很大帮助,因为它们使得机器生成的一方在用户生成的一方调用很少的通知功能变得容易且成本低,而不必去发布事件的麻烦.


cod*_*nix 5

我觉得没问题.但是如果你处理同一个类中的事件,你也可以覆盖事件方法:

protected override void OnClick(Eventargs e)
{
   base.OnClick(e);
}
Run Code Online (Sandbox Code Playgroud)

这样效率更高,并且可以在必要时为您提供吞下事件的能力(简单地不调用base.OnClick()).

  • 此外,它允许您指定是否希望代码在任何其他事件处理程序之前或之后(或两者兼而有之)运行. (2认同)