添加EventHandler + = EventHandler有什么影响?

时间:2011-07-08 10:12:37

标签: c# .net events .net-3.5

我在A类中有一个SelectionChanged事件,我希望通过B类中继。我假设在B类中声明一个SelectionChanged事件并将此EventHandler分配给A.SelectionChanged会导致<{1}}在触发B.SelectionChanged时触发 - 结果证明是错误的。

更清楚一些代码:

A.SelectionChanged

打印出“Relayed:false”。

将EventHandler添加到另一个EventHandler有什么影响?

修改 注意!我知道解决这个问题的方法是通过委托,函数等来传递事件,但我很想知道这段代码的效果是什么。

3 个答案:

答案 0 :(得分:2)

您的代码中没有任何内容可以“{连接”B.SelectionChangedA.SelectionChanged的调用。因此,当您在SelectionChanged上触发A时,不会调用在SelectionChanged上处理B的代理。

我认为你想要的是你在B上的事件充当A暴露的事件的适配器?如果是这种情况,您需要编写自己的add / remove逻辑。请参阅以下内容:

Events + Adapter Pattern

添加/删除的另一个例子:

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

答案 1 :(得分:2)

在这种情况下,B的SelectionChanged和A的SelectionChanged不相关。

如果你要让B继承自A并删除B上的第二个声明,那么这将有效。

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);
   }
}

或者您可以通过...

抽取信息
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);
   }

}

答案 2 :(得分:1)

事实证明,这是来自EventHandler作为委托的效果。这个类使用Delegate.Combine实现operator + = through(或者我假设)。该函数的文档为

  

连接指定多播(可组合)委托的调用列表。

所发生的情况是,分配给右侧EventHandler的所有处理程序都被添加到左侧的EventHandler中。在这种情况下,处理程序为零,因此没有任何反应。但是,如果更改了事物的顺序,以便在B.SelectionChanged连接到B.SelectionChanged之前分配A.SelectionChanged,则会正确连接事物。但是,从B中删除处理程序并不会将其从A中删除,因此应该高度重视。