2

しきい値をチェックするために必要な機能を持つ抽象クラス 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();
    }
  }
}
4

5 に答える 5

2

通常、従うべきフォームは次のとおりです。

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 型は、特定の型のイベントを作成するための優れたシンタックス シュガーです。右側のラムダ式はデフォルト ハンドラーに初期化するため、呼び出す前に null をチェックする必要はありません。

EventArgs はイベント固有の情報です。何もありませんが、もしそうなら、EventArgs をサブクラス化し、イベント レシーバーが必要とするあらゆるデータを入れます。

public event SomeEventNameとのペアのパターンは、 protected virtual void OnSomeEventMicrosoft によって .NET のイベント用に規定されています。これに従う必要はありません、これは .NET プログラマーが望んでいることです。

于 2012-11-30T18:36:59.133 に答える
1

基本クラス A でヘルパー メソッドを定義できます。

protected void FireNotification() 
{
    if (Notifier != null)
        Notifier();
}

オーバーライドされた からこれを呼び出しますCheckTreshold

于 2012-11-30T18:06:06.593 に答える
1

このコードにはいくつかの問題があります。

まず、イベントを定義するために EventHandler 組み込みデリゲートを使用する必要があります。次に、イベントを定義するクラスの外でイベントを発生させることはできません (そのため、子孫から Notify() を使用できません)。3 番目に、テンプレート メソッド デザイン パターンを使用して、基本クラスとその子孫の間のコントラクトをより明確に定義し、しきい値チェックの一部を実装できます。

最後に、継承階層が必要な理由がまったくわかりません。必要なすべてのロジックを 1 つのクラスに実装できますか? とにかく、コンパイルして正しく動作するコードは次のとおりです。

  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();
    }
  }
于 2012-11-30T19:22:44.570 に答える
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 のサンプルは、これらすべての規則に従っているわけではないことに注意してください。

于 2012-11-30T18:30:55.553 に答える
-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();
于 2012-11-30T18:09:10.620 に答える