英語で読む

次の方法で共有


IDisposable.Dispose メソッド

定義

アンマネージ リソースの解放またはリセットに関連付けられているアプリケーション定義のタスクを実行します。

public void Dispose ();

次の例は、 メソッドを実装する方法を Dispose 示しています。

using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(disposing: true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SuppressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;
            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# finalizer syntax for finalization code.
        // This finalizer will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide finalizer in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(disposing: false) is optimal in terms of
            // readability and maintainability.
            Dispose(disposing: false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

注釈

このメソッドを使用して、このインターフェイスを実装する クラスのインスタンスによって保持されているファイル、ストリーム、ハンドルなどのアンマネージ リソースを閉じるか解放します。 規則により、このメソッドは、オブジェクトによって保持されているリソースの解放、または再利用のためのオブジェクトの準備に関連するすべてのタスクに使用されます。

警告

IDisposableインターフェイスを実装するクラスを使用している場合は、クラスの使用が終了したら、そのDispose実装を呼び出す必要があります。 詳細については、「IDisposable 」の「IDisposable を実装するオブジェクトの使用」セクションを参照してください。

このメソッドを実装する場合は、コンテインメント階層を介して呼び出しを伝達することで、保持されているすべてのリソースが解放されていることを確認します。 たとえば、オブジェクト a がオブジェクト b を割り当て、オブジェクト b がオブジェクト c を割り当てる場合、Dispose実装は b に対してDisposeを呼び出す必要があります。Disposeこの場合、c を呼び出す必要があります。

重要

C++ コンパイラはリソースの決定的な破棄をサポートし、 Disposeメソッドを直接実装することはできません。

基底クラスが IDisposableを実装している場合、オブジェクトはその基底クラスの Disposeメソッドも呼び出す必要があります。 基底クラスとそのサブクラスにIDisposableを実装する方法の詳細については、「IDisposable」の「IDisposable および継承階層」セクションを参照してください。

オブジェクトのDisposeメソッドが 2 回以上呼び出された場合、オブジェクトは、最初の呼び出しの後すべての呼び出しを無視する必要があります。 メソッドが複数回呼び出される場合、オブジェクトは例外を Dispose スローしないでください。 リソースが既に破棄されている場合、Dispose以外のインスタンスメソッドはObjectDisposedExceptionをスローする可能性があります。

ユーザーは、リソースの種類が特定の規則を使用して、割り当てられた状態と解放された状態を示す必要がある場合があります。 その例として、従来はオープンまたはクローズと考えられているストリーム クラスがあります。 このような規則を持つクラスの実装者は、 メソッドを呼び出すカスタマイズされた名前 (など Close) を持つパブリック メソッドを Dispose 実装することを選択できます。

Disposeメソッドを明示的に呼び出す必要があるが、オブジェクトのコンシューマーがDisposeメソッドを呼び出し忘れ、アンマネージリソースが解放されないという危険性は常にあります。 この回避方法は次の 2 とおりあります。

  • マネージリソースをSystem.Runtime.InteropServices.SafeHandleから派生したオブジェクトでラップします。 次に、 Dispose実装は、 System.Runtime.InteropServices.SafeHandleインスタンスの Disposeメソッドを呼び出します。 詳細については、「Object.Finalize」の 「SafeHandle 代替」セクションを参照してください。

  • Disposeが呼び出されない場合にリソースを解放するには、ファイナライザーを実装します。 既定では、ガベージ コレクターは、メモリを再利用する前に、オブジェクトのファイナライザーを自動的に呼び出します。 ただし、 メソッドが Dispose 呼び出された場合、通常、ガベージ コレクターが破棄されたオブジェクトのファイナライザーを呼び出す必要はありません。 自動終了処理を回避するために、 Dispose実装ではGC.SuppressFinalizeメソッドを呼び出すことができます。

StreamWriterなどの、アンマネージリソースにアクセスするオブジェクトを使用する場合は、 usingステートメントを使用してインスタンスを作成することをお勧めします。 usingステートメントは、それを使用しているコードが完了すると、ストリームを自動的に閉じ、そのオブジェクトに対してDispose を呼び出します。 例については、 クラスを StreamWriter 参照してください。

適用対象

製品 バージョン
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

こちらもご覧ください