2

我的新客户处的代码审查清单具有以下内容 -

实现 Dispose 和 Finalize 的类应该在 Dispose 实现中调用 GC.SupressFinalize

为什么?

它不应该读作实现 IDisposable 接口的类应该在 Dispose 实现中调用 GC.SupressFinalize 吗?

还是我错过了一些愚蠢的东西?

4

2 回答 2

6

您错过了并非每个一次性类都需要终结器的事实 - 事实上,很少有人这样做,特别是由于 .NET 2.0 的SafeHandletype。如果没有终结器,为什么需要调用SuppressFinalize

于 2011-01-05T17:35:26.027 回答
1

这是准确的。如果 Dispose(bool) 方法完成了它的工作,那么让终结器再次完成它就没有任何意义了。调用 GC.SuppressFinalize() 是一种优化,您可以阻止 .NET 打扰调用一个什么都不做的终结器。

我注意到你用大写的 C 编写了 Class。这暗示你正在用 VB.NET 编写代码。请注意,IDE在 99.99% 的情况下都会做错事。一旦你在输入“Implements IDisposable”后按下 Enter,它就会插入错误的代码:

    Private disposedValue As Boolean = False        ' To detect redundant calls

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free other state (managed objects).
            End If

            ' TODO: free your own state (unmanaged objects).
            ' TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub

#Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

呸。这是终结器的样板实现,在 MSDN Library btw 中有详细记录。这是错的。真正需要终结器的情况极为罕见,.NET 类已经自己处理了它。如果您确实使用操作系统句柄,那么您应该使用 SafeHandle 派生类之一。或者编写自己的包装器。

将其编辑回此:

Public Sub Dispose() Implements IDisposable.Dispose
    someField.Dispose()
    '' maybe some more
    ''...
End Sub
于 2011-01-05T18:11:15.637 回答