Пересылка событий в С#
Я использую класс, который пересылает события в С#. Мне было интересно, есть ли способ сделать
это требует меньше накладных расходов кода.
Вот пример того, что у меня до сих пор.
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.
Ответы
Ответ 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"
}
}
}