我如何清除C#中的事件订阅?

以下面的C#类:

c1 { event EventHandler someEvent; } 

如果有很多订阅c1someEvent事件,我想清除它们,最好的方法是什么? 还要考虑这个事件的订阅可能是lambda /匿名代表。

目前我的解决scheme是添加一个ResetSubscriptions()方法给c1设置someEvent为null。 我不知道这是否有任何看不见的后果。

在类中,可以将(隐藏)variables设置为null。 空引用是有效地表示空调用列表的规范方式。

从课外,你不能这样做 – 事件基本上是暴露“订阅”和“取消订阅”,就是这样。

值得注意的是类场事件实际上在做什么 – 它们同时创build一个variables一个事件。 在课堂上,你最终会引用variables。 从外面,你参考事件。

查看我的关于事件和代表的文章以获取更多信息。

向c1添加一个方法,将'someEvent'设置为null …

 class c1 { event EventHandler someEvent; ResetSubscriptions() {someEvent = null;} } 
 class c1 { event EventHandler someEvent; ResetSubscriptions() {someEvent = delegate{};} } 

使用委托{}比null更好

清除所有订阅者的最佳实践是将someEvent设置为null,如果要将此function公开给外部,请添加另一个公共方法。 这没有看不到的后果。 前提是要记住用关键字“event”声明SomeEvent。

请参阅第125页的“C#4.0”一书。

这里有人提议使用Delegate.RemoveAll方法。 如果您使用它,示例代码可以按照下面的表格。 但这真的很愚蠢。 为什么不在ClearSubscribers()函数中只是SomeEvent=null

  public void ClearSubscribers () { SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null. } 

您可以通过使用Delegate.Remove或Delegate.RemoveAll方法来实现此目的。

在类中设置事件为null。 当你处理一个类的时候,你应该总是把事件设置为null,GC有事件的问题,如果事件悬而未决,可能不会清除已处理的类。

概念延长无聊的评论。

我宁愿使用“事件处理程序”而不是“事件”或“委托”这个词。 其他的东西使用“事件”一词。 在一些编程语言(VB.NET,Object Pascal,Objective-C)中,“event”被称为“消息”或“信号”,甚至有一个“消息”关键字和特定的糖语法。

 const WM_Paint = 998; // <-- "question" can be done by several talkers WM_Clear = 546; type MyWindowClass = class(Window) procedure NotEventHandlerMethod_1; procedure NotEventHandlerMethod_17; procedure DoPaintEventHandler; message WM_Paint; // <-- "answer" by this listener procedure DoClearEventHandler; message WM_Clear; end; 

而且,为了回应这个“消息”,一个“事件处理程序”响应,不pipe是单个代表还是多个代表。

总结:“事件”是“问题”,“事件处理程序”是答案。

删除所有事件,假设事件是一个“Action”types:

 Delegate[] dary = TermCheckScore.GetInvocationList(); if ( dary != null ) { foreach ( Delegate del in dary ) { TermCheckScore -= ( Action ) del; } }