2017-01-01 3 views
3

イベントを発生させて既存の加入者に通知したいと思います。しかし、私はまた、新規加入者には、加入した直後に発生したすべてのイベントを通知されることを期待しています。これは箱からでも可能ですか、それとも自分自身でその機能を実装する必要がありますか?今、私のコードは次のようになります。誰かがそれを購読する前にイベントを発生させる

public delegate void GridCompiled(int gridsize); 
public event GridCompiled OnGridCompiled; 

ctor(){ 
    if (OnGridCompiled != null) 
     OnGridCompiled(gridsize); 
} 

イベントが0の加入者を持っている場合、それは発生しません、それはまた、イベントが発生された後に加入する加入者に対して提起されることはありません。

私はそれを自分で実装する必要がある場合、私のオプションは何ですか?

+0

はやり過ぎかもしれないが、Rx.Netは 'Replay'方法を提供しますhttp://www.introtorx.com/Content/v1.0.10621.0/14_HotAndColdObservables.html#Replay – haim770

+5

のように私には思えますイベントではなくメッセージキューを探しています。 –

答えて

5

発生イベントの追跡がないので、機能を自分で実装する必要があります。あなたは順番に、あなたの前のイベントの引数を格納し、新しいイベントリスナーが追加されたときに、関連するイベントを実行するためのリストが必要になります

class Example { 
    private readonly List<GridCompiledEventArgs> m_previousEventArgs = new List<EventArgs>(); 
    private EventHandler<GridCompiledEventArgs> m_gridCompiled; 

    public event EventHandler<GridCompiledEventArgs> GridCompiled { 
     add { 
      //Raise previous events for the caller 
      foreach(GridCompiledEventArgs e in m_previousEventArgs) { 
       value(this, e); 
      } 
      //Add the event handler 
      m_gridCompiled += value; 
     } 
     remove { 
      m_gridCompiled -= value; 
     } 
    } 

    protected virtual void OnGridCompiled(GridCompiledEventArgs e) { 
     if (m_gridCompiled != null) { 
      m_gridCompiled(this, e); 
     } 
     m_previousEventArgs.Add(e); 
    } 
} 

あなたは、このソリューションのために検討した2つのものがあります。あなたがそれらをアドレスしたい場合は、あなたのソリューションはより複雑になります:

  1. GridCompiledEventArgsは、イベントハンドラによって変更することができる場合(例えば、呼び出し元にステータスを返すように)、イベント引数は、前のイベントに保存されますそれらの変更を含むリストまた、イベントハンドラがイベントargsへの参照を保持する場合、後で変更することさえできます。それを望まない場合は、m_previousEventArgsにコピーを保存し、「履歴」イベントを発生させる前に別のコピーを作成する必要があります。
  2. イベントを処理したり動作を変更する代わりに、派生クラスがOnGridCompiledメソッドをオーバーライドできるようにすることをお勧めします。派生クラスがOnGridCompiledを変更してイベントをインターセプトし、特定のケースでそれを発生させない場合は、OnGridCompiled(これは単に動作であるかもしれない)なしで発生するため、この動作は常に "履歴"イベントに適用されるとは限りません。変更する場合は、OnGridCompiledを経由するソリューションを実装する必要があります。これがオプションの場合は、protected virtualの代わりにsealedクラスとOnGridCompiledメソッドをprivateにすることで、この問題を回避できます。
+0

ありがとうございます。ポイント2はクラスがすでに封印されているため私のケースには適用されませんが、ポイント1を検討する必要があります。なぜプライベートイベントEventHandler m_gridCompiled; 'を書かなかったのですか? –

+1

イベントではないので'GridCompiled'はイベントです。 'm_gridCompiled'はイベントハンドラを格納するバッカーフィールドです。構文全体は、_eventメソッド構文_tと呼ばれます。 – Sefe

+0

多分私は私の質問に展開する必要があります。イベントを発生させたときに呼び出されるメソッドのリストとしてイベントを理解しています。このイベントではキーワード 'イベント 'が不可欠だと思いました。しかし、上記の例では、イベントハンドラを 'm_gridCompiled'(イベントではありません)に追加し、イベントを発生させるのと同じようにイベントハンドラを呼び出すことができます。コードの明瞭さのためにキーワード 'イベント'がありますか? –

関連する問題