我应该在 IDisposable 和 Finalize 上实现 GC.SupressFinalize 吗?

发布于 2024-10-10 16:05:57 字数 239 浏览 5 评论 0原文

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

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

为什么?

难道它不应该被理解为实现 IDisposable 接口的类应该在 Dispose 实现中调用 GC.SupressFinalize 吗?

或者我错过了一些愚蠢的事情?

The code review checklist in my new client place has the following -

Class implementing Dispose and Finalize should have a call to GC.SupressFinalize in Dispose implementation

Why?

Should it not read as Class implementing IDisposable interface should have a call to GC.SupressFinalize in the Dispose implementation?

Or Am I missing something silly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绾颜 2024-10-17 16:05:57

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

You're missing the fact that not every disposable class needs a finalizer - in fact, very few do, particularly due to .NET 2.0's SafeHandle type. If there's no finalizer, why would you need to call SuppressFinalize?

枫林﹌晚霞¤ 2024-10-17 16:05:57

这是准确的。如果 Dispose(bool) 方法完成了它的工作,那么就不再需要让终结器再次执行它。调用 GC.SuppressFinalize() 是一种优化,您可以阻止 .NET 费心调用不执行任何操作的终结器。

我注意到您用大写的 C 编写了 Class。这暗示您正在用 VB.NET 编写代码。请注意,在 99.99% 的情况下,IDE 都会执行错误。一旦您在输入“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

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

将其编辑回此:

Public Sub Dispose() Implements IDisposable.Dispose
    someField.Dispose()
    '' maybe some more
    ''...
End Sub

It's accurate. If the Dispose(bool) method did its job then there is no longer any point to let the finalizer do it again. Calling GC.SuppressFinalize() is an optimization, you stop .NET from bothering to call a finalizer that does nothing.

I noticed that you wrote Class with a capital C. That's a hint that you are writing your code in VB.NET. Watch out, the IDE does the wrong thing in 99.99% of all cases. As soon as you press Enter after typing "Implements IDisposable", it inserts the wrong code:

    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

Yuck. That's the boilerplate implementation of a finalizer, well documented in the MSDN Library btw. It's wrong. It is extremely rare to actually need a finalizer, the .NET classes already take care of it themselves. If you really do use an operating system handle then you should use one of the SafeHandle derived classes. Or write your own wrapper.

Edit it back to this:

Public Sub Dispose() Implements IDisposable.Dispose
    someField.Dispose()
    '' maybe some more
    ''...
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文