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 が何もしないファイナライザーをわざわざ呼び出さないようにします。

Class を大文字の C で記述していることに気付きました。これは、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 ライブラリで十分に文書化されています。それは間違っています。実際にファイナライザーが必要になることは非常にまれで、.NET クラスが既にそれを処理しています。実際にオペレーティング システム ハンドルを使用する場合は、SafeHandle 派生クラスのいずれかを使用する必要があります。または、独自のラッパーを作成します。

これを編集して次のように戻します。

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