C#事件连接在处理程序';s对象';s构造函数

本文关键字:对象 构造函数 程序 事件 连接 处理 | 更新日期: 2023-09-27 18:28:19

我正在尝试将interface.MessageReceived连接到logger.LogReceivedMessage。如果我加上界面MessageReceived+=LogReceivedMessage;在logger的构造函数中,按预期调用LogReceivedMessage

但是,如果我将连接移动到logger中的其他位置,则永远不会调用LogReceivedMessage

所有其他到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);
}

在没有将所有代码发布到整个项目的情况下,有人知道为什么这种行为会有所不同吗?

C#事件连接在处理程序';s对象';s构造函数

我想分享我对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