【问题标题】:How to invoke an event automatically when a function is called?调用函数时如何自动调用事件?
【发布时间】:2010-07-11 15:03:45
【问题描述】:

我有这样的代码:

public class Foo
{
  public SomeHandler OnBar;

  public virtual void Bar()
  {
  }
}

Foo 是一个基类,因此其他类可能会从它继承。
我希望在调用 Bar() 时始终触发 OnBar 事件,即使它没有在 Bar 内显式调用。
怎么办?

【问题讨论】:

    标签: c# .net events .net-3.5


    【解决方案1】:

    一个常见的模式是有一个非虚拟方法来做你想做的事,它调用一个虚拟方法。子类可以重写内部方法来更改功能,但公共方法可以是非虚拟的,始终首先引发事件。

    public class Foo
    {
        public SomeHandler OnBar;
    
        public void Bar()
        {
            if (OnBar != null)
            {
                OnBar(this, EventArgs.Empty);
            }
            BarImpl();
        }
    
        protected virtual void BarImpl()
        {
        }
    }
    

    【讨论】:

    • 基本上是模板方法模式+1的实现
    • 那么这是最好的方法吗?在 C++ 中,我会使用 bind() 从事件调用函数和原始函数中创建一个新函数。
    【解决方案2】:

    简短的回答:你不能。不是 Microsoft 为您提供的开箱即用的功能。

    也就是说,看看 .NET 中的“面向方面编程”。谷歌一下,你可能会得到一些有用的东西。

    补充:标准方法是在Bar() 方法中引发事件,然后要求所有派生类调用基本实现。但你不能强制执行。

    【讨论】:

      【解决方案3】:

      首先,您提供的代码无法编译。
      虚函数必须有一个主体。

      要确保触发事件,您可以执行以下操作。

      public class Foo
      {
        public SomeHandler OnBar;
      
        public void Bar()
        {
           OnBar();  (check for nulls)
           ProtectedBar();
        }
      
        protected virtual ProtectedBar()
        {
        }
      }
      

      【讨论】:

      • 你是对的。但是,在这种情况下,这并不重要。这只是为了证明该功能可以被覆盖。我不知道你为什么被否决。我赞成平衡。
      • 您提供的代码也无法编译 - 您的虚函数没有返回类型,您的评论也不是评论。
      • Dan Puzey:只是按照问题的风格:P
      【解决方案4】:

      正如 Vilx- 所说,我想做这类事情的更好方法是使用面向方面的编程。

      这将帮助您处理“纠缠代码”(即在不应该承担此责任的方法中调用事件)和“分散代码”(即在许多方法中调用相同的事件,复制您的代码)问题。

      你应该看看postsharp,它有一个免费的社区版。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 2018-03-17
        • 1970-01-01
        相关资源
        最近更新 更多