2009-11-11 64 views
1

理想我想要一個功能類似於下面的所有事件(這個例子不編譯):C#如何拆除和清理

void AddRemoveEvent<TEvent, TArgs>(TEvent e, EventHandler<TArgs> h, bool add) 
     where TArgs : System.EventArgs 
    { 
     if (add) 
     { 
      e += h; 
     } 
     else 
     { 
      e -= h; 
     } 
    } 

然後,我可以寫功能:

void AddRemoveEvents(bool add) 
{ 
    AddRemoveEvent(aMemberControl.Click, OnClick, add); 
} 

我然後知道我可以再次調用該函數來刪除所有處理程序。我想這將是比寫,保持和依靠保持同步兩種功能強:

void AddEvents(bool add) 
{ 
    aMemberControl.Click += OnClick; 
} 

void RemoveEvents(bool add) 
{ 
    aMemberControl.Click -= OnClick; 
} 

一個同事寫了一個方便的類,它這種東西,使用反射。這非常有用,但它依賴於作爲字符串傳入的事件的名稱。我正在尋找一個型安全版本。有沒有人有任何想法,如果有可能寫這個?

謝謝。

我知道我不應該在任何地方取消連線,因爲垃圾收集器應該照顧大多數情況。但是,有時候一個流浪事件會導致泄漏,所以我發現嘗試刪除所有添加的事件會更安全,而不是試圖與分析器混淆,試圖找出導致問題的事件。

我見過此相關的問題:
How to remove all event handlers from a control

回答

3

你不能做到這一點直接,很遺憾。在C#中沒有直接以安全方式提供的「事件對象」。你可以做到這一點,如果你有EventInfo,但你必須得到這個名字。例如:

void AddRemoveEvent(object target, string name, Delegate handler, bool add) 
    where TArgs : System.EventArgs 
{ 
    EventInfo info = target.GetType().GetEvent(name); 
    // Error handling left as an exercise for the reader :) 
    if (add) 
    { 
     info.AddEventHandler(target, handler); 
    } 
    else 
    { 
     info.RemoveEventHandler(target, handler); 
    } 
} 

不是非常好的:(

我不知道我這個單一的方法麻煩,順便說一句 - 我只希望有單獨的addEventHandler和RemoveEventHandler方法也許有。一個常見的方法來獲取EventInfo,確保它存在並且是適當的類型等 - 但不是布爾值來指示添加/刪除。

1

用C#3.5魔術字符串可以在許多情況下用表達式樹。有很多例子需要將字符串傳遞給INotifyPropertyChanged的PropertyChanged事件。 ntNhibernate很好地利用這個特性來表達一些類型屬性的行爲。

然後,您可以說刪除((MyControlType t) => t.Click)。使用來自其他Stackoverflow文章的代碼,您可能會離開而不指定實際方法是事件處理程序。