7

在 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()call Dispose(False)。为什么 IDE 也不添加这个?我必须自己添加它,还是以某种方式隐式调用它?

编辑:知道为什么 IDE 会自动添加 80% 的所需内容但忽略 Finalize 方法吗?这种功能的全部意义不在于帮助您不要忘记这些事情吗?

EDIT2:谢谢大家的出色回答,现在这很有意义!

4

4 回答 4

11

如果您实际上持有垃圾收集器不会自动清理的非托管资源并在 Dispose() 中清理这些资源,那么是的,您应该在 Finalize() 中执行相同的操作。

如果您出于其他原因实施 IDisposable,则不需要实施 Finalize()。

基本问题是这样的:如果没有调用 Dispose() 并且您的对象被垃圾收集,内存会泄漏吗?如果是,则执行 Finalize。如果没有,你不需要。此外,避免“仅仅因为它更安全”而实施 Finalize。具有自定义终结器的对象可能需要两次 GC 传递来释放它们——一次将它们放入待处理的终结器队列,第二次传递以实际释放它们的内存。

于 2008-09-22T05:59:04.357 回答
3

不,除非您有非托管资源要清理,否则您不需要 Finalize。

在大多数情况下,类是一次性的原因是因为它保留了对其他托管 IDisposable 对象的引用。在这种情况下,不需要或不需要 Finalize 方法。

于 2008-09-22T06:02:27.920 回答
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
于 2009-12-12T06:55:24.893 回答
1

正如其他人所说,除非您直接持有非托管资源,否则您不需要实现终结器。此外,假设您在 .NET 2.0 或更高版本中工作,您不太可能需要实现终结器,因为通常可以使用 SafeHandle 来包装您的非托管资源。

不久前,我写了一篇相当长的博客文章,介绍了 IDisposable 和终结器的背景和实现,如果您不完全清楚,可能值得一读。

于 2008-09-22T06:59:11.450 回答