VB.NET-在实现IDisposable时是否应该添加Finalize方法?
在Visual Studio中,当我键入"Implements IDisposable
"行时,IDE会自动添加:
- 一个
disposedValue
成员变量 - Sub Dispose()实现IDisposable.Dispose
Sub Dispose(ByVal以布尔方式进行处理)
应该将Dispose()保留下来,并将清理代码放入Dispose(dispose)中。
但是Dispose Finalize Pattern表示我们还应该重写Sub Finalize()来调用Dispose(False)。为什么IDE也不添加此内容?我必须自己添加它,还是以某种方式隐式调用它?
编辑:知道为什么IDE会自动添加80%的所需内容,却忽略了Finalize方法吗?难道不是这种功能的全部目的就是要不要忘记这些东西吗?
EDIT2:谢谢大家的出色回答,现在这很有意义!
解决方案
如果我们实际上持有的非托管资源将不会被垃圾收集器自动清理,并在Dispose()中清理这些资源,那么可以,我们应该在Finalize()中执行相同的操作。
如果由于其他原因要实现IDisposable,则不需要实现Finalize()。
基本问题是这样的:如果未调用Dispose()并收集了对象垃圾,会发生内存泄漏吗?如果是,请执行Finalize。如果不是,则不需要。另外,请避免仅出于"更安全"而实施Finalize。具有自定义终结器的对象可能需要两次GC释放才能释放它们-一次将它们放置在挂起的终结器队列中,而第二次释放则实际上释放它们的内存。
不,除非我们有非托管资源需要清理,否则不需要Finalize。
在大多数情况下,类为可抛弃型的原因是因为它保留了对其他托管IDisposable对象的引用。在这种情况下,不需要或者不需要Finalize方法。
正如其他人所说,除非直接持有非托管资源,否则无需实现终结器。另外,假设我们在.NET 2.0或者更高版本中工作,则不太可能不需要实现终结器,因为通常可以使用SafeHandle来包装非托管资源。
我写了一篇相当长的博客文章,其中介绍了IDisposable和finalizers的背景和实现,如果我们不太清楚,那么可能值得一读。
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