在C#中转发事件

时间:2009-06-30 18:54:08

标签: c# events event-handling c#-2.0

我正在使用一个在C#中转发事件的类。我想知道是否有办法 它需要更少的代码开销。

这是我到目前为止的一个例子。

class A
{
   public event EventType EventA;
}

class B
{
   A m_A = new A();
   public event EventType EventB;

   public B()
   {
      m_A.EventA += OnEventA;
   }

   public void OnEventA()
   {
      if( EventB )
      {
         EventB();
      }
   }
}

A类引发原始事件。 B类将其转发为EventB(基本上是同一事件)。 A类对其他模块是隐藏的,因此无法直接订阅EventA。

我正在尝试做的是减少B类中用于转发事件的代码开销,因为通常没有真正处理类B中的事件。此外,我将有几个不同的事件,因此它需要编写一个B类中的许多OnEvent()方法只用于转发事件。

是否可以以某种方式自动将EventA链接到EventB,所以我会有这样的事情:

class B
{
   A m_A = new A();
   public event EventType EventB;

   public B()
   {
      m_A.EventA += EventB; // EventA automatically raises EventB.
   }
}

我正在使用C#2.0编译器btw。

2 个答案:

答案 0 :(得分:77)

绝对:

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

    public event EventType EventB
    {
        add { m_a.EventA += value; }
        remove { m_a.EventA -= value; }
    }
}

换句话说,Eve​​ntB订阅/取消订阅代码只是将订阅/取消订阅请求传递给EventA。

请注意,这不允许您为订阅EventB的订阅者举起事件。这就像将某人的地址直接传递给大众营销公司,而您原来的方式更像是自己订阅大众营销公司,并允许人们要求您将邮件的副本发送给他们。

答案 1 :(得分:11)

IMO,您的原始代码(或多或少)正确无误。特别是,它允许您提供正确的sender(对于认为他们订阅B上的活动的人来说,B实例应该是class B { A m_A = new A(); private EventType eventB; public event EventType EventB { add { // only subscribe when we have a subscriber ourselves bool first = eventB == null; eventB += value; if(first && eventB != null) m_A.EventA += OnEventB; } remove { // unsubscribe if we have no more subscribers eventB -= value; if(eventB == null) m_A.EventA -= OnEventB; } } protected void OnEventB(object sender, EventArgsType args) { eventB?.Invoke(this, args); // note "this", not "sender" } }

如果事件未订阅,有一些技巧可以减少运行时的开销,但这会增加更多代码:

{{1}}