ファイナライザー (C# プログラミング ガイド)Finalizers (C# Programming Guide)

ファイナライザーは、クラスのインスタンスを破棄するために使います。Finalizers are used to destruct instances of classes.

コメントRemarks

  • ファイナライザーは、構造体には定義できません。Finalizers cannot be defined in structs. クラスでだけ使用します。They are only used with classes.

  • クラスで使用できるファイナライザーは 1 つだけです。A class can only have one finalizer.

  • ファイナライザーを継承またはオーバーロードすることはできません。Finalizers cannot be inherited or overloaded.

  • ファイナライザーを呼び出すことはできません。Finalizers cannot be called. デストラクターは自動的に起動されます。They are invoked automatically.

  • ファイナライザーは修飾子を取らず、パラメーターはありません。A finalizer does not take modifiers or have parameters.

たとえば、次はクラス Car に対するファイナライザーの宣言です。For example, the following is a declaration of a finalizer for the Car class.

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

ファイナライザーは、式本体の定義として実行することもできます。次に例を示します。A finalizer can also be implemented as an expression body definition, as the following example shows.

using System;

public class Destroyer
{
   public override string ToString() => GetType().Name;
   
   ~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");
}

ファイナライザーは、オブジェクトの基底クラスで Finalize を暗黙的に呼び出します。The finalizer implicitly calls Finalize on the base class of the object. そのため、ファイナライザーの呼び出しは、暗黙的に次のコードに解釈されます。Therefore, a call to a finalizer is implicitly translated to the following code:

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

つまり、派生が最も多いクラスから派生が最も少ないクラスまで、継承チェーンのすべてのインスタンスに対して、Finalize メソッドが再帰的に呼び出されます。This means that the Finalize method is called recursively for all instances in the inheritance chain, from the most-derived to the least-derived.

注意

空のファイナライザーは使用しないでください。Empty finalizers should not be used. ファイナライザーがクラスに存在するときは、エントリが Finalize キューで作成されます。When a class contains a finalizer, an entry is created in the Finalize queue. ファイナライザーを呼び出すと、ガベージ コレクターが呼び出され、このキューを処理します。When the finalizer is called, the garbage collector is invoked to process the queue. ファイナライザーが空の場合、パフォーマンスを不必要に低下させるだけです。An empty finalizer just causes a needless loss of performance.

ファイナライザーがいつ呼び出されるかはガベージ コレクターによって決定されるため、プログラマは制御できません。The programmer has no control over when the finalizer is called because this is determined by the garbage collector. ガベージ コレクターは、アプリケーションが使用していないオブジェクトをチェックします。The garbage collector checks for objects that are no longer being used by the application. 終了処理が可能なオブジェクトと考えられる場合、ファイナライザー (存在する場合) を呼び出し、オブジェクトの格納に使用されているメモリを解放します。If it considers an object eligible for finalization, it calls the finalizer (if any) and reclaims the memory used to store the object.

(.NET Core アプリケーションではなく) .NET Framework アプリケーションでは、プログラムが存在する場合、ファイナライザーも呼び出されます。In .NET Framework applications (but not in .NET Core applications), finalizers are also called when the program exits.

Collect を呼び出すことによって、ガベージ コレクションを強制的に行うことができます。ただし、パフォーマンスに問題が発生する可能性があるため、通常はこの処理を避けます。It is possible to force garbage collection by calling Collect, but most of the time, this should be avoided because it may create performance issues.

ファイナライザーを使ったリソースの解放Using Finalizers to Release Resources

一般に C# では、ガベージ コレクションでランタイムにターゲットを設定しない言語で開発する場合ほど、メモリ管理を必要としません。In general, C# does not require as much memory management as is needed when you develop with a language that does not target a runtime with garbage collection. .NET Framework のガベージ コレクターが、オブジェクトに対するメモリの割り当てと解放を暗黙的に管理するからです。This is because the .NET Framework garbage collector implicitly manages the allocation and release of memory for your objects. ただし、ウィンドウ、ファイル、ネットワーク接続などのアンマネージ リソースをアプリケーションでカプセル化するとき、ファイナライザーを使ってこれらのリソースを解放する必要があります。However, when your application encapsulates unmanaged resources such as windows, files, and network connections, you should use finalizers to free those resources. 終了処理が可能なオブジェクトの場合、ガベージ コレクターはそのオブジェクトの Finalize メソッドを実行します。When the object is eligible for finalization, the garbage collector runs the Finalize method of the object.

リソースの明示的な解放Explicit Release of Resources

アプリケーションで高額な外部リソースを使用している場合、ガベージ コレクターがオブジェクトを解放する前にリソースを明示的に解放する手段を用意することが推奨されます。If your application is using an expensive external resource, we also recommend that you provide a way to explicitly release the resource before the garbage collector frees the object. この処理を行うには、オブジェクトに対して必要なクリーンアップを実行する Dispose メソッドを IDisposable インターフェイスから実装します。You do this by implementing a Dispose method from the IDisposable interface that performs the necessary cleanup for the object. これによって、アプリケーションのパフォーマンスを大幅に向上させることができます。This can considerably improve the performance of the application. このようにリソースを明示的に制御する場合でも、ファイナライザーは、Dispose メソッドの呼び出しが失敗したときにリソースをクリーンアップするための安全装置になります。Even with this explicit control over resources, the finalizer becomes a safeguard to clean up resources if the call to the Dispose method failed.

リソースのクリーンアップの詳細については、次のトピックを参照してください。For more details about cleaning up resources, see the following topics:

Example

次の例では、継承チェーンを形成する 3 つのクラスを作成します。The following example creates three classes that make a chain of inheritance. First が基底クラスであり、SecondFirst から派生し、ThirdSecond から派生します。The class First is the base class, Second is derived from First, and Third is derived from Second. 3 つのクラスのいずれにもファイナライザーがあります。All three have finalizers. Main では、派生が最も多いクラスのインスタンスが作成されます。In Main, an instance of the most-derived class is created. プログラムを実行すると、3 つのクラスのファイナライザーが派生が最も多いクラスから派生が最も少ないクラスの順に自動的に呼び出されます。When the program runs, notice that the finalizers for the three classes are called automatically, and in order, from the most-derived to the least-derived.

class First
{
    ~First()
    {
        System.Diagnostics.Trace.WriteLine("First's finalizer is called.");
    }
}

class Second : First
{
    ~Second()
    {
        System.Diagnostics.Trace.WriteLine("Second's finalizer is called.");
    }
}

class Third : Second
{
    ~Third()
    {
        System.Diagnostics.Trace.WriteLine("Third's finalizer is called.");
    }
}

class TestFinalizers
{
    static void Main()
    {
        Third t = new Third();
    }

}
/* Output (to VS Output Window):
    Third's finalizer is called.
    Second's finalizer is called.
    First's finalizer is called.
*/

C# 言語仕様C# Language Specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

参照See Also