的your answer - 这里有两个问题...
第一:在这两种情况下,你提出了错误的发送者的外部事件。有人订阅外部类别的活动,预计这些类别将通过该外部类别的发件人进行募集。
这对于winform控件或绑定列表实现,其中发件人用于识别共享处理程序的许多对象之间的对象尤为重要。
这应该不是是这样的:
void Inner_AnEvent(object sender, EventArgs e) {
var handler = AnEvent;
if (handler != null) handler(this, e);
}
第二(更小的)问题是,你正在服用了事件的内部类,即使外部类没有订户。你可以修复这个更多的自定义处理...
private EventHandler anEvent;
public event EventHandler AnEvent {
add { // note: not synchronized
bool first = anEvent == null;
anEvent += value;
if(first && anEvent != null && inner != null) {
inner.SomeEvent += Inner_AnEvent;
}
}
remove { // note: not synchronized
bool hadValue = anEvent != null;
anEvent -= value;
if(hadValue && anEvent == null && inner != null) {
inner.SomeEvent -= Inner_AnEvent;
}
}
}
(以及类似的代码在内蒙古获取/设置成只订阅,如果我们有听众......
if(value != null && anEvent != null)
value.AnEvent += Inner_AnEvent;
如果你有很多的outer-的实例,这可能是一个很大的保护但很少使用事件
其中,我认为唯一的语义正确的方法是第一个。甚至超出谁是“发件人”财产应报告的问题(这可能是有点模糊的情况下收到订阅的对象不是启动动作的对象)还有一个问题o f如果一个对象为一个内部和外部类实例的事件订阅方法,然后取消订阅一个方法,会发生什么。即使重复取消一个实例的事件,也不应取消订阅另一个事件。 – supercat 2012-05-22 19:02:33