110

クラスのデストラクタと Finalize メソッドの違いは何ですか?

私は最近、Visual Studio 2008 がデストラクタを Finalize メソッドと同義と見なしていることを発見しました。つまり、Visual Studio ではクラス内で両方のメソッドを同時に定義することはできません。

たとえば、次のコード フラグメント:

class TestFinalize
{
    ~TestFinalize()
    {
        Finalize();
    }

    public bool Finalize()
    {
        return true;
    }
}

デストラクタで Finalize を呼び出すと、次のエラーが発生します。

次のメソッドまたはプロパティ間の呼び出しがあいまいです: 'TestFinalize.~TestFinalize()' と 'TestFinalize.Finalize()'

また、Finalize の呼び出しがコメント化されている場合、次のエラーが発生します。

タイプ 'ManagementConcepts.Service.TestFinalize' は、同じパラメーター タイプで 'Finalize' というメンバーを既に定義しています

4

3 に答える 3

75

ウィキペディアには、ファイナライザーとデストラクタの違いについて、ファイナライザーの記事でいくつかの良い議論があります

C#には実際には「真の」デストラクタはありません。構文はC++デストラクタに似ていますが、実際にはファイナライザです。例の最初の部分で正しく記述しました。

~ClassName() { }

上記はFinalize関数のシンタックスシュガーです。ベース内のファイナライザーの実行が保証されますが、それ以外はFinalize関数のオーバーライドと同じです。これは、デストラクタ構文を作成するときに、実際にファイナライザーを作成していることを意味します。

Microsoftによると、ファイナライザーはガベージコレクターが()を収集するときに呼び出す関数を指しFinalize、デストラクタは結果として実行されるコードのビットです(構文上のシュガーは)になりFinalizeます。それらは同じものに非常に近いので、Microsoftは決して区別するべきではありませんでした。

MicrosoftによるC++の「デストラクタ」という用語の使用は誤解を招く可能性があります。これは、C ++では、オブジェクトが削除またはスタックからポップされるとすぐに同じスレッドで実行されるのに対し、C#では別の時間に別のスレッドで実行されるためです。

于 2011-11-28T16:45:56.743 に答える
73

C# のデストラクタはSystem.Object.Finalizeメソッドをオーバーライドします。そのためには、デストラクタ構文を使用する必要があります。手動でオーバーライドFinalizeすると、エラー メッセージが表示されます。

Finalize基本的に、メソッド宣言でやろうとしていることは、基本クラスのメソッドを隠していることです。これにより、コンパイラは警告を発行しますが、new修飾子を使用して黙らせることができます (機能する場合)。ここで注意すべき重要なことは、同じ名前のメンバーを同時に宣言することはできないため、デストラクタとメソッドの両方を使用するとエラーが発生することです (推奨されません、メソッドを宣言することはできます)。デストラクタを宣言していません)。overridenewFinalizepublic new void Finalize()

于 2009-07-02T22:30:48.323 に答える
21

ここにあります: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

  1. デストラクタ

    これらは、オブジェクトのクリーンアップ コードを含む特別なメソッドです。これらは GC によって暗黙的に呼び出されるため、コードで明示的に呼び出すことはできません。~C# では、前に記号が付いたクラス名と同じ名前になります。お気に入り-

    Class MyClass
    {
    
    ~MyClass()
    {
    .....
    }
    }
    

    VB.NET では、デストラクタは System.Object クラスの Finalize メソッドをオーバーライドすることによって実装されます。

  2. 廃棄

    これらは、クラス内の他のメソッドと同様に明示的に呼び出すことができますが、オブジェクトをクリーンアップするという特別な目的があります。dispose メソッドでは、オブジェクトのクリーンアップ コードを記述します。データベース接続、ファイルなど、dispose メソッドですべてのアンマネージ リソースを解放することが重要です。dispose メソッドを実装するクラスは、IDisposable インターフェイスを実装する必要があります。Dispose メソッドは、破棄するオブジェクトの GC.SuppressFinalize メソッドを呼び出す必要がありますクラスは既にオブジェクトをクリーンアップする作業を行っているため、デスタクタを持っています。その場合、ガベージ コレクタがオブジェクトの Finalize メソッドを呼び出す必要はありません。参照: http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

  3. ファイナライズ

    Finalize メソッドは、Dispose メソッドが呼び出されない場合にリソースをクリーンアップするためのセーフガードとして機能します。アンマネージ リソースをクリーンアップするには、Finalize メソッドのみを実装する必要があります。ガベージ コレクターはマネージド リソースを自動的にクリーンアップするため、マネージド オブジェクトに対して Finalize メソッドを実装しないでください。Finalize メソッドは GC によって暗黙的に呼び出されるため、コードから呼び出すことはできません。

    注: C# では Finalize メソッドをオーバーライドできないため、内部実装が MSIL の Finalize メソッドをオーバーライドするデストラクタを使用する必要があります。しかし、VB.NET では、Finalize メソッドはデストラクタ メソッドをサポートしているためオーバーライドできます。

更新: 興味深い半関連スレッドはこちら.

于 2009-07-02T22:30:24.297 に答える