【C#】Disposeパターン

using

usingは自動的に、finallyで必ずDispose()を呼び出すtry...finallyを作成するだけ。
ただし、メンバ等にはusingが使えない。。。⇒Disposeパターン

Dispose()の必須事項

  1. 安全に複数回呼び出し可能であること
  2. インスタンスが保持しているリソース(OSや外部DLLが管理するもの)を解放すること
  3. 必要ならば、基本クラスのDispose()を呼ぶこと
  4. このクラスのファイナライザを抑制して、GCがファイナライズキュー上のオブジェクト数を減らすための手助けをする
  5. 基本的に例外をスローしない

Disposeパターン

マネージドリソースとアンマネージドリソースを解放
ベースクラス
IDisposeを継承し、Dispose()、Dispose(bool disposing)、ファイナライザを実装
解放処理はDispose(bool disposing)で行い、Dispose()とファイナライザをそれを呼び出す
サブクラス
Dispose(bool disposing)のみをオーバーライド


public class Base : System.IDisposable
{
  private bool isDisposed; // Disposeされたかを表すフラグ
  
  public Dispose()
  {
    this.Dispose(true); // 解放処理はDispose(bool disposing)で行い、Dispose()とファイナライザをそれを呼び出す
    System.GC.SuppressFinalize(this); // 二重解放を避ける
  }
  
  ~Base()
  {
    this.Dispose(false); // 解放処理はDispose(bool disposing)で行い、Dispose()とファイナライザをそれを呼び出す
  }
  
  
  protected virtual void Dispose(bool dispose)
  {
    if (this.isDisposed) return; // 安全に複数回呼び出し可能
    if (dispose)
    {
      // マネージリソースの解放(ex:ストリーム)
    }
    
    // アンマネージリソースの解放
    
    this.isDisposed = true; // 安全に複数回呼び出し可能
  }
}
Visual Studioならば、1行目の時点で、「破棄パターンを使ってインターフェイスを実装します」ある程度作成してくれる。