提升事件的模式

时间:2012-11-30 18:00:14

标签: c# event-handling

我有一个抽象类A,它具有检查阈值所需的功能。当违反阈值时,我想要提出一个事件通知我。我在Qt中做过很多次这样的事情,但我似乎无法弄清楚如何将它转移到C#。这是我目前想到的结构。

namespace N
{
  abstract class A
  {
    public delegate void Notify();
    public event Notify Notifier;
    public abstract void CheckThreshold();
  }

  class B : A
  {
    public override void CheckThreshold()
    {
       Notifier();
    }
  }

  class N
  {
    public AlertMe()
    {
    }
    public static Main()
    {
      var b = new B();
      b.Notifier += new A.Notify(AlertMe);

      b.CheckThreshold();
    }
  }
}

5 个答案:

答案 0 :(得分:1)

您可以在基类A

中定义辅助方法
protected void FireNotification() 
{
    if (Notifier != null)
        Notifier();
}

并从被覆盖的CheckTreshold调用此内容。

答案 1 :(得分:1)

通常,您要关注的表单是:

public event EventHandler<SomeEventArgs> SomeEvent = (s, e) => { };

protected virtual void OnSomeEvent(SomeEventArgs e)
{
    SomeEvent(this, e);
}

所以在你的情况下你可能想要:

abstract class A {

    public event EventHandler<EventArgs> ThresholdExceeded = (s, e) => { };

    protected virtual void OnThresholdExceeded(EventArgs e)
    {
        ThresholdExceeded(e);
    }

    public abstract void CheckThreshold();
}

class B : A {
    public override void CheckThreshold()
    {
        if (/* your condition */) OnThresholdExceeded(new EventArgs());
    }
}

现在有一些事情--EventHandler类型是一个很好的语法糖,用于制作特定类型的事件。右边的lambda表达式将它初始化为默认处理程序,因此在调用它之前不必将其检查为null。

EventArgs是特定于事件的信息 - 您没有,但如果您这样做,您将继承EventArgs并输入您的事件接收器所需的任何数据。

Microsoft为.NET中的事件规定了public event SomeEventNameprotected virtual void OnSomeEvent对的模式。你没有拥有来遵循这一点,但这是.NET程序员想要的。

答案 2 :(得分:1)

此代码存在多个问题。

首先,您应该使用EventHandler内置委托来定义事件。其次,你不能在定义它的类之外引发一个事件(这就是为什么你不能使用后代的Notify())。第三,你可以使用Template Method Design Pattern并更清楚地定义你的基类和它后代之间的契约,并实现threashold检查的一部分。

最后我根本不明白为什么你需要继承层次结构呢?也许你可以在一个类中实现所有必需的逻辑?但无论如何这里的代码将编译和行为正确:

  abstract class A
  {
    // Avoid defining custom delegate at all because there is a lot of 
    // build-in events for every case, like EventHandler<T>, 
    // Func<T>, Action<T> etc
    // public delegate void Notify();
    public event EventHandler ThreasholdViolated;

    protected void OnThreasholdViolated()
    {
       var handler = ThreasholdViolated;
       if (handler != null)
         handler(this, EventArgs.Empty);
    }

    public abstract void CheckThreshold();
  }

  class B : A
  {
    public override void CheckThreshold()
    {
       OnThreasholdViolated();
    }
  }

答案 3 :(得分:0)

通常的模式是在基类中提供受保护的虚方法,如http://msdn.microsoft.com/en-us/library/vstudio/9aackb16(v=vs.100).aspx所示。该方法名称的约定是On [EventName]并接受事件args实例。

还遵循使用EventHandler或EventHandler作为委托的约定,并提供事件发起者和相应的参数。您可以在http://msdn.microsoft.com/en-us/library/vstudio/ms229011(v=vs.100).aspx中找到有关此内容的更多信息。请注意,来自MSDN的示例不遵循所有这些约定。

答案 4 :(得分:-1)

public abstract class A
{
    public EventHandler<EventArgs> OnThresholdViolated;

    public abstract void CheckThreshold();
}

public class B : A
{
    public B(EventHandler<EventArgs> alertMe) {
        OnThresholdViolated += alertMe;
    }

    public override void CheckThreshold()
    {
        if (null != OnThresholdViolated)
        {
            OnThresholdViolated(this, EventArgs.Empty);
        }
    }
}

然后使用:

打电话
        B b = new B(AlertMe);

        b.CheckThreshold();