C# Disposeの実装

C#にてClassにDisposeを実装する方法を説明します。

マネジーリソースとアンマネージリソース

リソースの種類は、CLRが管理するマネージリソースとCLRが管理しないアンマネージリソースに分けられる。

マネージリソースは、ガーベージコレクションによって自動的に解放される。

アンマネージリソースは、開発者の責任で解放しなければならない。

※マイクロソフト提供のクラスは、ガーベージコレクションのマネージリソース回収のときに、アンマネージリソースの解放も一緒に行われるようになっている。

自分でアンマネージリソースを扱った実装をするクラスは、

ガーベージコレクションはあくまでマネージリソースしか回収しないので、アンマネージリソースは自分で解放するよう実装しなければならない。

※ガーベージコレクションが回収を開始するのは、マネージリソースが足りなくなったときに限られる。アンマネージリソースが足りなくなっても、ガーベージコレクションは何もしない。なのでアンマネージリソースの解放を怠るとメモリリークが発生する。

IDisposablインターフェイスでDispose()を実装する(基本的な使い方)

上記の方法では、Dispose()を使用するのには不足です。

IDisposableインターフェイスの実装目的

1.ガーベージコレクションに頼らず、コード上での明示の解放が必要であることを示す。

2.IDisposableが実装されているということは、クラスがファイル、ストリーム、およびハンドルなどのアンマネージリソースを利用していることを示す。

IDisposableを実装に満たす要件

1.Dispose()では、マネージリソース・アンマネージリソースの解放処理を行う。

2.Dispose()が呼び出されなかった場合、ガーベージコレクションによってマネージリソースの回収が行われる際に、アンマネージリソースの解放するように、デストラクタに実装する。

3.既に解放済みのリソースにもかかわらず、ガベコレの回収によって、デストラクタが呼び出されるとFinalizeキューが処理され、パフォーマンスの低下させるので、GC.SuppressFinalize(obj)を用い、Finalizeの呼び出しが不要なオブジェクトを指定し、デストラクタがガーベージコレクションの対象外となるようにする。

4.Dispose()は複数回呼び出される可能性があるので、複数回呼び出されても問題のないように実装する。

そこで以下のように修正します。

 

コメントを残す