0

に接続しようとしinterface.MessageReceivedていlogger.LogReceivedMessageます。interface.MessageReceived += LogReceivedMessage; を追加すると、inloggerのコンストラクターLogReceivedMessageは、期待どおりに呼び出されます。

ただし、フックアップを 内の別の場所に移動するとloggerLogReceivedMessageは呼び出されません。

他のすべてのフックアップはinterface.MessageReceived使用する必要がありますが、それは問題では+=ありませ=ん。

ウォッチ ウィンドウと Visual Studio の [オブジェクト ID の作成] オプションを使用して、コードがinterface両方の場所で同じインスタンスを持っていることを確認しました。します。ただし、interface.MessageReceivedコンストラクターには、コード内の他の場所とは異なるオブジェクトがあります。実際、何かを接続するたびに変化するようです。それが期待されているかどうかはわかりません。

コンストラクターでのみハンドラーを接続できる理由は誰にもありますか?

編集: 動作するようになりましたが、なぜ動作するのかわかりません。interfaceクラスの元のコード:

public event Action<Message> MessageReceived;
busClient.MessageReceived += MessageReceived

私はそれを次のように変更しました:

public event Action<Message> intermediateMessageReceived;
public event Action<Message> MessageReceived;
busClient.MessageReceived += intermediateMessageReceived;

public void intermediateMessageReceived(Message m)
{
   MessageReceived(m);
}

プロジェクト全体にすべてのコードを投稿せずに、なぜこれが異なる動作をするのか誰にもわかりませんか?

4

1 に答える 1

1

この問題に関連する C# のイベントについて学んだことを共有したいと思います。イベントがどのように機能するかを理解していなかったため、問題が発生しました。

イベント B をイベント A にサブスクライブすると、イベント A を呼び出すと、イベント B から A へのサブスクリプションの時点でイベント B にサブスクライブされていたものだけが呼び出されます。B のサブスクライバーが変更された場合、その変更はイベント A が呼び出されたときに反映されません。

次のコードは、次のことを示しています。

namespace EventDemonstrator
{
   class Program
   {
      class BottomLayer
      {
         public event System.Action<string> Event;
        public void callEvent() { Event("bottom"); }
      }
      class MiddleLayer
      {
         public void HookUpEvent(BottomLayer bl) { bl.Event += this.Event; }
         public event System.Action<string> Event;
      }
      class TopLayer
      {
         public void TopLayerHandler(string s)
         {
            System.Console.Write(string.Format(" {0} top\n", s));
         }
      }

      static void HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top)
      {
         middle.HookUpEvent(bottom);
         middle.Event += top.TopLayerHandler;
         try {bottom.callEvent(); }
         catch (System.NullReferenceException) { System.Console.Write("HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom: Event was null\n"); }
      }

      static void HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top)
      {
         middle.Event += top.TopLayerHandler;
         middle.HookUpEvent(bottom);
         System.Console.Write("HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom:");
         bottom.callEvent();
      }

      static void Main(string[] args)
      {
         HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom(new BottomLayer(), new MiddleLayer(), new TopLayer());
         HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom(new BottomLayer(), new MiddleLayer(), new TopLayer());
      }
   }
}

出力:

HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom: Event was null
HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom: bottom top
于 2013-09-16T15:30:59.190 に答える