我正在使用一个在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。
答案 0 :(得分:77)
绝对:
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的订阅者举起只事件。这就像将某人的地址直接传递给大众营销公司,而您原来的方式更像是自己订阅大众营销公司,并允许人们要求您将邮件的副本发送给他们。
答案 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}}