我越是深入研究C#和GC,我发现越来越多的东西我不太确定。我一直认为只有在我的课程中有一些非托管资源时才需要Dispose和相应的Finalizer。
但我有很多场合只有本地C#类,如果我需要Dispose和相应的Finalizer,我不太清楚。例如,当我将事件处理程序附加到我的事件时。
调用Dispose时是否需要删除事件处理程序。还有人告诉我,如果事件处理程序仍然附加,则可能无法收集该对象。如果是这种情况,GC会以某种方式受到损害。
是否可以总结我何时以及如何实现Dispose和Finalizer?
事实上我对此有更多疑问,但也许这个问题的答案可以帮助我进一步。
答案 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
方法中处理。