【问题标题】:Should I implement GC.SupressFinalize on IDisposable AND Finalize?我应该在 IDisposable AND Finalize 上实施 GC.SupressFinalize 吗?
【发布时间】:2011-01-05 17:32:43
【问题描述】:
我的新客户处的代码审查清单具有以下内容 -
实现 Dispose 和 Finalize 的类应该在 Dispose 实现中调用 GC.SupressFinalize
为什么?
它不应该读作实现 IDisposable 接口的类应该在 Dispose 实现中调用 GC.SupressFinalize 吗?
或者我错过了什么愚蠢的东西?
【问题讨论】:
标签:
.net
garbage-collection
idisposable
finalizer
suppressfinalize
【解决方案2】:
这是准确的。如果 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