的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