VB.NET - 在实现IDisposable时是否应该添加Finalize方法?

时间:2008-09-22 05:07:43

标签: vb.net dispose idisposable destructor finalize

在Visual Studio中,当我键入“Implements IDisposable”行时,IDE会自动添加:

  • disposedValue成员变量
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

Dispose()应保持不变,清理代码应放在Dispose(disposing)中。

Dispose Finalize Pattern表示您还应覆盖Sub Finalize()以致电Dispose(False)。为什么IDE也不添加这个?我必须自己添加,还是以某种方式隐式调用?

编辑:任何想法为什么IDE会自动添加80%的必需内容但却省略了Finalize方法?这种功能的重点不在于帮助您忘记这些事情吗?

EDIT2:谢谢大家的优秀答案,现在这很有道理!

4 个答案:

答案 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和终结者的背景和实现,如果你不完全清楚它,可能值得一读。

相关问题