web-dev-qa-db-ja.com

デストラクタ、破棄、およびファイナライズメソッドの違い

ガベージコレクターがC#でどのように機能するかを研究しています。 DestructorDispose、およびFinalizeメソッドの使用について混乱しています。

私の研究と理解によれば、クラス内にDestructorメソッドを持っていると、クラスのインスタンスで明示的に呼び出せないデストラクタメソッドで述べられている方法でガベージコレクションを実行するようにガベージコレクタに指示します。

Disposeメソッドは、ユーザーにガベージコレクションを制御するためのものです。 Finalizeメソッドは、クラスが使用したリソースを解放しますが、オブジェクト自体は解放しません。

私はそれを正しい方法で理解しているかどうかはわかりません。疑問を明確にしてください。その他のリンクまたはガイドを歓迎します。

61

デストラクタは暗黙的にFinalizeメソッドを呼び出しますが、技術的には同じです。 Disposeは、IDisposableインターフェイスを実装するオブジェクトで使用できます。

表示される場合があります: Destructors C#-MSDN

デストラクタは、オブジェクトの基本クラスでFinalizeを暗黙的に呼び出します。

同じリンクの例:

class Car
{
    ~Car()  // destructor
    {
        // cleanup statements...
    }
}

デストラクタコードは、暗黙的に次のコードに変換されます。

protected override void Finalize()
{
    try
    {
        // Cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

デストラクタに対するあなたの理解は正しい:

[〜#〜] msdn [〜#〜] から

プログラマは、デストラクタが呼び出されるタイミングを制御できません。これは、ガベージコレクタによって決定されるためです。ガベージコレクターは、アプリケーションで使用されなくなったオブジェクトをチェックします。オブジェクトが破棄に適格であると判断した場合、デストラクタ(存在する場合)を呼び出し、オブジェクトの格納に使用されたメモリを回収します。デストラクタは、プログラムの終了時にも呼び出されます。 Collectを呼び出すことでガベージコレクションを強制することは可能ですが、ほとんどの場合、パフォーマンスの問題が発生する可能性があるため、これは避ける必要があります。

54
Habib

C#の用語では、デストラクタとファイナライザは基本的に交換可能な概念であり、外部ハンドルなどの型が収集されるときにnmanagedリソースを解放するために使用する必要があります。 veryファイナライザを書く必要があることはまれです。

それに伴う問題は、GCが非決定的であるため、Dispose()メソッド(IDisposable経由)により、deterministicクリーンアップ。これはガベージコレクションとは無関係で、呼び出し元がリソースを解放できるようにしますsooner。また、managedリソース(アンマネージに加えて)での使用にも適しています。たとえば、encapsulates(たとえば)データベース接続、タイプを破棄して接続も解放したい場合があります。

41
Marc Gravell