我是否必须删除处理程序

时间:2015-03-16 18:26:23

标签: c# .net events eventhandler

我越是深入研究C#和GC,我发现越来越多的东西我不太确定。我一直认为只有在我的课程中有一些非托管资源时才需要Dispose和相应的Finalizer。

但我有很多场合只有本地C#类,如果我需要Dispose和相应的Finalizer,我不太清楚。例如,当我将事件处理程序附加到我的事件时。

调用Dispose时是否需要删除事件处理程序。还有人告诉我,如果事件处理程序仍然附加,则可能无法收集该对象。如果是这种情况,GC会以某种方式受到损害。

是否可以总结我何时以及如何实现Dispose和Finalizer?

事实上我对此有更多疑问,但也许这个问题的答案可以帮助我进一步。

1 个答案:

答案 0 :(得分:4)

清除您何时进行Dispose和Finalize的一般问题:

如果您的班级中有一个IntPtr字段(或其他类型的非托管资源,但最常见的是IntPtr),那么您的班级责任就是清理该字段然后你需要实现一个终结器。在该终结器中,您应该释放IntPtr指向的任何资源。如果你没有IntPtr,那么你所持有的类应该处理它自己的定型并实现IDisposeable(参见下一部分)

如果您的班级中有一个实现IDisposable的字段,并且您的班级负责清理该对象后,您的班级也应该实施IDisposable,并且在该dispose方法中,您应该调用{{1}在对象上。

对于事件处理程序,这是个人偏好的问题。你可以这样做,但只有在你做if the person who subscribed to the event messed up their code时才有意义。

  

除非您希望该活动的发布者能够超过该活动   订阅者,没有理由删除事件处理程序...

我个人没有,但我确实知道有些人这样做。如果你想这样做,那么这个过程只是在你的dispose方法中将事件处理程序设置为Dispose()

null

编辑:好的一点Hans Passant brought up in the comments:你永远不会需要一个终结者,如果你有一个需要终结者的非托管资源,它应该被包裹在{{3包装器为您处理完成。一旦你这样做,对象就变成另一个正常的public sealed class Example : IDisposable { public EventHandler MyEvent; public void Dispose() { MyEvent = null; } } ,你需要在IDisposable方法中处理。