Должен ли я реализовать GC.SupressFinalize для IDisposable И Finalize? - PullRequest
2 голосов
/ 05 января 2011

Контрольный список проверки кода в моем новом клиентском месте имеет следующее -

Класс, реализующий Dispose и Finalize, должен иметь вызов GC.SupressFinalize в реализации Dispose

Почему?

Разве это не должно читаться как класс, реализующий интерфейс IDisposable, должен иметь вызов GC.SupressFinalize в реализации Dispose?

Или я что-то упустил глупо?

Ответы [ 2 ]

6 голосов
/ 05 января 2011

Вам не хватает того факта, что не каждому одноразовому классу нужен финализатор - на самом деле, очень немногие нуждаются в , особенно из-за .NET 2.0's SafeHandle type . Если финализатора нет, зачем вам звонить SuppressFinalize?

1 голос
/ 05 января 2011

Это точно.Если метод Dispose (bool) выполнил свою работу, то больше нет смысла позволять финализатору делать это снова.Вызов GC.SuppressFinalize () - это оптимизация, вы не позволяете .NET беспокоиться о вызове финализатора, который ничего не делает.

Я заметил, что вы написали Class с заглавной буквы C. Это подсказка, что вы пишете свой кодв VB.NETОбратите внимание: среда IDE делает ошибку неправильно в 99,99% всех случаев.Как только вы нажимаете Enter после ввода «Implements IDisposable», он вставляет неправильный код:

    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
...