7

Visual Studio で " Implements IDisposable" という行を入力すると、IDE によって次のものが自動的に追加されます。

  • メンバーdisposedValue変数
  • aSub Dispose() Implements IDisposable.Dispose
  • aSub Dispose(ByVal disposing As Boolean)

はそのDispose()ままにして、クリーンアップ コードを に配置する必要がありますDispose(disposing)

ただし、Dispose Finalize パターンSub Finalize()は、 callをオーバーライドする必要があることも示していますDispose(False)。なぜIDEもこれを追加しないのですか? 自分で追加する必要がありますか、それとも何らかの方法で暗黙的に呼び出されますか?

編集: IDE が必要なものの 80% を自動的に追加するのに、Finalize メソッドを省略している理由がわかりませんか? この種の機能の要点は、これらのことを忘れないようにすることではないでしょうか?

EDIT2:素晴らしい回答をありがとうございました。これは完全に理にかなっています!

4

4 に答える 4

11

ガベージ コレクターによって自動的にクリーンアップされない非管理リソースを実際に保持していて、それらを Dispose() でクリーンアップする場合は、Finalize() でも同じことを行う必要があります。

他の理由で IDisposable を実装している場合は、Finalize() を実装する必要はありません。

基本的な質問は次のとおりです: Dispose() が呼び出されず、オブジェクトのガベージ コレクションが行われなかった場合、メモリ リークは発生しますか? はいの場合、ファイナライズを実装します。いいえの場合は、その必要はありません。また、「安全だから」という理由だけで Finalize を実装することは避けてください。カスタム ファイナライザーを持つオブジェクトは、それらを解放するために 2 つの GC パスが必要になる可能性があります。

于 2008-09-22T05:59:04.357 に答える
3

いいえ、クリーンアップするアンマネージド リソースがない限り、Finalize は必要ありません。

ほとんどの場合、クラスが使い捨てである理由は、他のマネージ IDisposable オブジェクトへの参照を保持しているためです。この場合、Finalize メソッドは不要または望ましくありません。

于 2008-09-22T06:02:27.920 に答える
2
Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub
于 2009-12-12T06:55:24.893 に答える
1

他の人が言ったように、管理されていないリソースを直接保持していない限り、ファイナライザーを実装する必要はありません。また、.NET 2.0 以降で作業していると仮定すると、通常は SafeHandle を使用してアンマネージ リソースをラップできるため、ファイナライザーを実装する必要はほとんどありません。

IDisposable とファイナライザーの背景と実装について説明したかなり長いブログ記事を少し前に書きました。

于 2008-09-22T06:59:11.450 に答える