役に立ちそうもないTips移転版

俺得なTipsを書き連ねるだけのブログ。

IDisposableとFinalizeのはざまで

タイトルはともかく。

.netでIDisposableを実装したとき、Finalizeはどーすりゃええん? という話だが。
IDisposable実装の作法も含めてこういう話。

  1. アンマネージリソースを(直接、間接に)扱ってれば、IDisposableは実装しとく。
  2. アンマネージリソースを扱うことがないのなら、IDisposableは実装しちゃダメ(人間が見てDisposeせんならんと思ってしまう)
  3. IDisposableを書くときは、必ず引数なしとboolean引数ありの二つをどっちもオーバライド。(下記参照)
  4. IDisposableを実装したらFinalizeも必ず書く。(Dispose()の呼び忘れを、ランタイムに拾わせるように)
  5. と、上記のお約束の上で、
    • 引数なしDispose()では、Dispose(true)を呼んで、GC.SuppressFinalize(this)。
    • Finalize()では、Dispose(false)を呼ぶ。何か継承してたらその後でbase.Finalize()。
    • 引数ありのDispose(boolean)で、リソースのクリーンアップを実装する。
      (引数trueのときだけマネージリソース(あれば)のクリーンアップをするように。
      さらにマネージリソースは複数回クリーンアップしないように仕込み入れておく。)
      そしてアンマネージリソースは引数に関わらずクリーンアップし(ただし複数回はしないように)、
      最後にbase.Dispose(boolean)を呼ぶ。
      (this.Dispose()が例外吐くかもなら、try-catch-finally仕掛けてfinallyできっちりbase.Dispose(boolean)を呼ぶように。)

おおよそのところは
(MSDN)アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装
(MSDN)CLR 徹底解剖: IDisposable について
また、他に
IDisposable を実装している型からの継承:Gushwell's Dev Notes
とか。