C#のDisposeパターン
クラスを作成するときに,クラス内で使用するリソースを適切に開放するために,IDisposable
インターフェイスを実装します.
IDisposableを実装するときに,以下のように「Disposeパターンを使って明示的にインターフェイスを実装します」という項目があるのでそれを使ってみると.
このような雛形が追加されます.(日本語部分は私がメモとして追加)
private bool disposedValue; protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects).管理リソースの開放 } // TODO: free unmanaged resources (unmanaged objects) and override finalizer // TODO: set large fields to null // 非管理リソースの開放 // 一時ファイルなどを削除したり,大きなフィールドにnullをセットするなど disposedValue = true; } } // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources: 非管理リソースの開放が必要な場合のみ,このデストラクタを有効にする // ~TemporaryFile() // { // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method // Dispose(disposing: false); // } void IDisposable.Dispose() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method Dispose(disposing: true); GC.SuppressFinalize(this); }
と,Visual Studioで用意してくれる雛形に合わせて,それぞれ管理リソースと非管理リソースの開放処理を記述すると良いです.
IDisposableについての詳しい解説は以下の記事がとてもわかり易いです. 管理リソースの開放,非管理リソースの開放はそれぞれどこに書くのか,どうしてそこに書くのか,についてとても丁寧に書かれています.
大事な点としては,
- 非管理リソースは確実に開放するためにデストラクタからも開放されるようにする
- 管理リソースの開放は.NET Frameworkに任せるので,デストラクタには開放処理を書かない
これらを満たすために上のようなDisposeパターンが使われる.
Disposeパターンを使った非管理リソースの開放については以下の記事にちょっと書きました.