CS.IDISP.DTOR

IDisposable を実装するときに、デストラクター (ファイナライザー) を提供します。

この規則は、Idisposable インターフェイスを実装しているクラスで、ファイナライザー (デストラクター) を実装していないコードを識別します。一部のクラスでは、クラスによって割り当てられたリソースをユーザーが解放できるように、Idisposable インターフェイスを実装しています。ただし、ユーザーは Dispose メソッドを呼び出すことを忘れる可能性があります。防御的にコーディングするには、そのようなクラスがファイナライザー (C# 内のデストラクター、管理された C++) も確実に実装するようにしてください。これにより、ユーザーが Dispose メソッドを呼び出すことを忘れても、ガベージコレクターがファイナライザーを呼び出すときに、リソースは解放されます。

脆弱性とリスク

標準の設計パターンを実装しなければ、メモリの管理ミスのリスクが高まります。

軽減と防止

問題は、Idisposable インターフェイスを実装し、デストラクターから Dispose() を呼び出すことで修正されます。

脆弱コード例

コピー
  using System;
  public class A : Idisposable
  {
      private bool _alreadyDisposed = false;
      public A()
      {
          // resource allocated here
      }
      public virtual void Dispose()
     {
         Dispose(true);
     }
     public virtual void Dispose(bool isDisposing)
     {
         if (_alreadyDisposed)
         {
             return;
         }
         if (isDisposing)
         {
             // Free managed resources
         }
         // Free unmanaged resources
         _alreadyDisposed = true;
     }
     // VIOLATION: Does not implement the destructor.
     // However, Idisposable interface is implemented.
 }

修正コード例

コピー
  // Problem is fixed by implementing Idisposable interface
  // and calling Dispose() from the destructor.
  Using System;
  public class A : Idisposable
  {
      private bool _alreadyDisposed = false;
      public A()
      {
          // resource allocated here
     }
     // FIXED: Destructor implemented.
     // Also note the call to GC.SuppressFinalize().
     ~A()
     {
         // Dispose() called from the destructor
         Dispose(false);
     }
     public virtual void Dispose()
     {
         Dispose(true);
         GC.SuppressFinalize();
     }
     public virtual void Dispose(bool isDisposing)
     {
         if (_alreadyDisposed)
         {
             return;
         }
         if (isDisposing)
         {
             // Free managed resources
         }
         // Free unmanaged resources
         _alreadyDisposed = true;
     }
 }

リファレンス: .NET Framework General Reference、Class Library デベロッパー向けの設計ガイドライン。