繁体   English   中英

C#事件连接仅在处理程序对象的构造函数中起作用

[英]C# event hookup works in in handler's object's constructor only

我正在尝试将interface.MessageReceivedlogger.LogReceivedMessage 如果我添加interface.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#事件。 我们不了解事件是如何工作的,这导致了问题。

当您将事件B订阅到事件A时,调用事件A只会调用将事件B订阅到事件B时所订阅的事件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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM