Подтвердить что ты не робот

Пересылка событий в С#

Я использую класс, который пересылает события в С#. Мне было интересно, есть ли способ сделать это требует меньше накладных расходов кода.

Вот пример того, что у меня до сих пор.

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. Также у меня будет несколько разных событий, поэтому потребуется написать много методов OnEvent() в классе B, которые служат только для пересылки событий.

Можно ли автоматически связать EventA с EventB каким-то образом, поэтому у меня было бы что-то вроде этого:

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

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

Я использую компилятор С# 2.0.

4b9b3361

Ответ 1

Абсолютно:

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

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

Другими словами, код подписки/отмены подписки EventB просто передает запросы подписки/отмены подписки на EventA.

Обратите внимание, что это не позволяет вам поднимать событие только для подписчиков, подписавшихся на EventB. Это как передача кому-то адреса непосредственно в компанию массового маркетинга, в то время как ваш оригинальный способ больше похож на подписку на компанию массового маркетинга и позволяет людям просить вас отправлять копии писем им.

Ответ 2

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) {
      EventType handler = eventB;
      if( handler !=null ) {
         handler(this, args); // note "this", not "sender"
      }
   }
}