开发者

What are the effects of adding EventHandler += EventHandler?

I have a SelectionChanged event in class A that I want to relay through class B. I assumed that declaring a SelectionChanged event in class B and assigning this EventHandler to A.SelectionChanged would cause B.SelectionChanged to trigger whenever A.SelectionChanged was triggered - this turned out to be false.

To be more clear, some code:

class A
{
   public event EventHandler SelectionChanged;

   public void TriggerSelectionChanged()
   {
      if (SelectionChanged != null) SelectionChanged(this, EventArgs.Empty);
   }
}

class B
{
   private A _a = new A();

   public A A { get { return _a; } }

   public event EventHandler SelectionChanged;

   public B()
   {
      A.SelectionChanged += SelectionChanged;
   }

   public static void Test()
   {
      B relayer = new B();
      bool wasRelayed = false;
      relayer.SelectionChanged += delegate { wasRelayed = true; };
      relayer.A.TriggerSelectionChanged();

      System.Console.WriteLine("Relayed: {0}", wasRelayed);
   }
}
开发者_StackOverflow中文版

This prints out "Relayed: false".

What are the effects of adding an EventHandler to another EventHandler?

EDIT: Note! I'm aware of that a solution to this is to relay the event through an delegate, function etc etc, but I'm mostly interrested in knowning what the effects of this code is.


There is nothing in your code that 'connects' the invocation of B.SelectionChanged to A.SelectionChanged. Therefore, when you fire a SelectionChanged on A, your delegate that handles SelectionChanged on B is not invoked.

I think what you want is for your event on B to acts as an adapter on the event that A exposes? If this is the case, you will need to write your own add / remove logic. See the following:

Events + Adapter Pattern

Another example of add / remove:

C#: event with explicity add/remove != typical event?


In this case B's SelectionChanged and A's SelectionChanged are not related.

If you were to make B inherit from A and remove the second declaration on B then this would work.

class A
{
   public EventHandler SelectionChanged;

   public void TriggerSelectionChanged()
   {
      if (SelectionChanged != null) SelectionChanged(this, EventArgs.Empty);
   }
}

class B : A
{
   public static void Test()
   {
      B relayer = new B();
      bool wasRelayed = false;
      relayer.SelectionChanged += delegate { wasRelayed = true; };
      relayer.TriggerSelectionChanged();

      System.Console.WriteLine("Relayed: {0}", wasRelayed);
   }
}

Or you can pump your messages through...

class A
{
   public EventHandler SelectionChanged;

   public void TriggerSelectionChanged()
   {
      if (SelectionChanged != null) SelectionChanged(this, EventArgs.Empty);
   }
}

class B
{
   public B()
   {
     this._a.SelectionChanged += (o, s) => 
     {
       if(this.SelectionChanged != null) { this.SelectionChange(o, s); }
     };
   }




private A _a = new A();

   public A A { get { return _a; } }

   public EventHandler SelectionChanged;

   public static void Test()
   {
      B relayer = new B();
      bool wasRelayed = false;
      relayer.SelectionChanged += delegate { wasRelayed = true; };
      relayer.A.TriggerSelectionChanged();
      System.Console.WriteLine("Relayed: {0}", wasRelayed);
   }

}


It turns out that this is an effect from EventHandler being a Delegate. This class implements operator += through (or so I assume) using Delegate.Combine. The documentation of this function reads

Concatenates the invocation lists of the specified multicast (combinable) delegates.

What happens is that all handlers assigned to the EventHandler on the right side are added to the EventHandler on the left. In this case there's zero handlers so nothing happens. However, if the order of things are changed such that B.SelectionChanged is assigned before B.SelectionChanged is connected to A.SelectionChanged things are hooked up correctly. However, removing an handler from B does not remove it from A so doing this should be highly frawned upon.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜