クラスのデストラクタと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」というメンバーを既に定義しています
C#のデストラクタは_System.Object.Finalize
_メソッドをオーバーライドします。あなたはそうするためにデストラクタ構文を使用する必要があります。 Finalize
を手動でオーバーライドすると、エラーメッセージが表示されます。
基本的にFinalize
メソッドの宣言でやろうとしていることは、 hiding 基本クラスのメソッドです。これにより、コンパイラはnew
修飾子を使用して黙らせることができる警告を発行します(動作する場合)。ここで注意すべき重要なことは、同じ名前のoverride
メンバーとnew
メンバーの両方を宣言できないことです同時に、デストラクタとFinalize
メソッドの両方を使用するとエラーが発生します(ただし、canは推奨されませんが、デストラクタを宣言していない場合は、public new void Finalize()
メソッドを宣言します)。
ウィキペディアには、 finalizer 記事のファイナライザーと デストラクタ の違いについての良い議論があります。
C#には「真の」デストラクタはありません。構文はC++デストラクタに似ていますが、実際にはファイナライザです。例の最初の部分で正しく書きました。
~ClassName() { }
上記はFinalize
関数の構文糖衣です。ベースのファイナライザの実行が保証されますが、それ以外はFinalize
関数のオーバーライドと同じです。これは、デストラクタ構文を記述するとき、実際にファイナライザを記述することを意味します。
Microsoftによると 、ファイナライザはガベージコレクタが収集するときに呼び出す関数(Finalize
)を参照しますが、デストラクタは結果として実行されるコードの一部です(構文Finalize
になる砂糖。それらは同じものに非常に近いので、Microsoftは決して区別するべきではありませんでした。
C++ではオブジェクトが削除またはスタックからポップされるとすぐに同じスレッドで実行されるのに対し、C#では別のスレッドで実行されるため、MicrosoftによるC++の「デストラクタ」という用語の使用は誤解を招きます。
ここにあります:http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html
デストラクタ
これらは、オブジェクトのクリーンアップコードを含む特別なメソッドです。 GCによって暗黙的に呼び出されるため、コード内で明示的に呼び出すことはできません。 C#では、
~
記号が前に付いたクラス名と同じ名前になります。いいねClass MyClass { ~MyClass() { ..... } }
VB.NETでは、デストラクタはSystem.ObjectクラスのFinalizeメソッドをオーバーライドすることにより実装されます。
廃棄する
これらはクラスの他のメソッドと同様であり、明示的に呼び出すことができますが、オブジェクトをクリーンアップするという特別な目的があります。 disposeメソッドでは、オブジェクトのクリーンアップコードを記述します。データベース接続やファイルなどのdisposeメソッドのアンマネージリソースをすべて解放することが重要です。disposeメソッドを実装するクラスは、IDisposableインターフェイスを実装する必要があります。Disposeメソッドは、破棄するオブジェクトのGC.SuppressFinalizeメソッドを呼び出すクラスにはオブジェクトをクリーンアップする作業が既に行われているため、クラスにはデストラクターがあり、ガベージコレクターがオブジェクトのFinalizeメソッドを呼び出す必要はありません。参照: http://msdn2.Microsoft.com/en-us/library/aa720161(VS.71).aspx
ファイナライズ
Finalizeメソッドは、Disposeメソッドが呼び出されない場合にリソースをクリーンアップするためのセーフガードとして機能します。管理されていないリソースをクリーンアップするには、Finalizeメソッドのみを実装する必要があります。ガベージコレクターは管理対象リソースを自動的にクリーンアップするため、管理対象オブジェクトにはFinalizeメソッドを実装しないでください。 FinalizeメソッドはGCによって暗黙的に呼び出されるため、コードから呼び出すことはできません。
注:C#では、Finalizeメソッドはオーバーライドできないため、MSILのFinalizeメソッドをオーバーライドする内部実装を持つデストラクタを使用する必要がありますが、 VB.NET、Finalizeメソッドは、デストラクタメソッドをサポートしているため、オーバーライドできます。
更新:興味深い半関連スレッドはこちら .