在Visual Studio中,当我键入“Implements IDisposable
”行时,IDE会自动添加:
disposedValue
成员变量Sub Dispose() Implements IDisposable.Dispose
Sub Dispose(ByVal disposing As Boolean)
Dispose()
应保持不变,清理代码应放在Dispose(disposing)
中。
但Dispose Finalize Pattern表示您还应覆盖Sub Finalize()
以致电Dispose(False)
。为什么IDE也不添加这个?我必须自己添加,还是以某种方式隐式调用?
编辑:任何想法为什么IDE会自动添加80%的必需内容但却省略了Finalize方法?这种功能的重点不在于帮助您不忘记这些事情吗?
EDIT2:谢谢大家的优秀答案,现在这很有道理!
答案 0 :(得分:11)
如果你实际上持有垃圾收集器不会自动清理的非托管资源并在Dispose()中清理它们,那么是的,你应该在Finalize()中做同样的事情。
如果由于其他原因而实施IDisposable,则不需要实现Finalize()。
基本问题是:如果没有调用Dispose()并且收集了对象垃圾,内存是否会泄漏?如果是,请执行Finalize。如果不是,你不需要。另外,避免实施Finalize“只是因为它更安全”。具有自定义终结器的对象可能需要两个GC传递来释放它们 - 一次将它们放在挂起的终结器队列中,另一次传递以实际释放它们的内存。
答案 1 :(得分:3)
不,除非您有非托管资源要清理,否则您无需进行终结。
在大多数情况下,类是一次性的原因是因为它保留了对其他托管的IDisposable对象的引用。在这种情况下,不需要或不需要Finalize方法。
答案 2 :(得分:2)
Implements IDisposable
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overloads Sub Dispose(ByVal disposing As Boolean)
If disposing Then
' Free other state (managed objects).
End If
' Free your own state (unmanaged objects).
' Set large fields to null.
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
答案 3 :(得分:1)
正如其他人所说,除非你直接持有非托管资源,否则你不需要实现终结器。此外,假设您使用的是.NET 2.0或更高版本,则您不太可能需要实现终结器,因为通常可以使用SafeHandle来包装您的非托管资源。
我写了一篇fairly long blog post,介绍了IDisposable和终结者的背景和实现,如果你不完全清楚它,可能值得一读。