デストラクタ (C# プログラミング ガイド)
更新 : 2007 年 11 月
デストラクタは、クラスのインスタンスを消滅させるために使用します。
解説
デストラクタは、構造体には定義できません。クラスでだけ使用します。
クラスで使用できるデストラクタは 1 つだけです。
デストラクタを継承またはオーバーロードすることはできません。
デストラクタを呼び出すことはできません。デストラクタは自動的に起動されます。
デストラクタは修飾子をとらず、パラメータはありません。
次に示すのは、Car クラスに対するデストラクタの宣言の例です。
class Car
{
~Car() // destructor
{
// cleanup statements...
}
}
デストラクタは、オブジェクトの基本クラスで Finalize を暗黙的に呼び出します。したがって、前のデストラクタのコードは、暗黙的に次のコードに解釈されます。
protected override void Finalize()
{
try
{
// Cleanup statements...
}
finally
{
base.Finalize();
}
}
つまり、最派生クラスから最低派生クラスまで、継承チェーンのすべてのインスタンスに対して、Finalize メソッドが再帰的に呼び出されます。
メモ : |
---|
空のデストラクタは使用しないでください。デストラクタがクラスに存在するときは、エントリが Finalize キューで作成されます。デストラクタを呼び出すと、ガベージ コレクタが呼び出され、このキューを処理します。デストラクタが空の場合は、パフォーマンスを不必要に低下させるだけです。 |
デストラクタがいつ呼び出されるかはガベージ コレクタによって決定されるため、プログラマは制御できません。ガベージ コレクタは、アプリケーションが使用していないオブジェクトをチェックします。消滅できるオブジェクトと考えられる場合、デストラクタ (存在する場合) を呼び出し、オブジェクトの格納に使用されているメモリをクリアします。デストラクタは、プログラムの終了時にも呼び出されます。
Collect を呼び出すことによって、ガベージ コレクションを強制的に行うことができます。ただし、パフォーマンスに問題が発生する可能性があるため、通常はこの処理を避けます。
デストラクタを使ったリソースの解放
一般に C# では、ガベージ コレクションを使用しない言語で開発する場合ほど、メモリ管理を必要としません。.NET Framework のガベージ コレクタが、オブジェクトに対するメモリの割り当てと解放を暗黙的に管理します。ただし、ウィンドウ、ファイル、ネットワーク接続などのアンマネージ リソースをアプリケーションでカプセル化するときは、デストラクタを使ってこれらのリソースを解放する必要があります。オブジェクトを消滅させることができる場合、ガベージ コレクタはそのオブジェクトの Finalize メソッドを実行します。
リソースの明示的な解放
アプリケーションで貴重な外部リソースを使用している場合は、ガベージ コレクタがオブジェクトを解放する前にリソースを明示的に解放する手段を用意することをお勧めします。この処理を行うには、オブジェクトに対して必要なクリーンアップを実行する Dispose メソッドを IDisposable インターフェイスから実装します。これによって、アプリケーションのパフォーマンスを大幅に向上させることができます。このようにリソースを明示的に制御する場合でも、デストラクタは、Dispose メソッドの呼び出しが失敗したときにリソースをクリーンアップするための安全装置になります。
リソースのクリーンアップの詳細については、次のトピックを参照してください。
使用例
次の例では、継承のチェインを形成する 3 つのクラスを作成します。First が基本クラスであり、Second は First から派生し、Third は Second から派生しています。3 つのクラスのいずれにもデストラクタがあります。Main() では、最派生クラスのインスタンスが作成されます。プログラムを実行すると、3 つのクラスのデストラクタが、最派生クラスから最低派生クラスの順に自動的に呼び出されます。
class First
{
~First()
{
System.Diagnostics.Trace.WriteLine("First's destructor is called.");
}
}
class Second : First
{
~Second()
{
System.Diagnostics.Trace.WriteLine("Second's destructor is called.");
}
}
class Third : Second
{
~Third()
{
System.Diagnostics.Trace.WriteLine("Third's destructor is called.");
}
}
class TestDestructors
{
static void Main()
{
Third t = new Third();
}
}
/* Output (to VS Output Window):
Third's destructor is called.
Second's destructor is called.
First's destructor is called.
*/
C# 言語仕様
詳細については、「C# 言語仕様」の次のセクションを参照してください。
1.6.7.6 デストラクタ
10.3.9.4 デストラクタ用に予約されているメンバ名
10.13 デストラクタ (クラス)
11.3.9 デストラクタ (構造体)