C#のクラスで、別のC#のクラスをラップする場合、デストラクタはどう実装すれば良いのだろうか。C#の場合、デストラクタが呼び出されるタイミングは不定である。
C++/CLIのクラスで、C++クラス(ネイティブコード)をラップする場合は、ネイティブコードのインスタンスを生成して代入するネイティブコードのポインタをメンバとして定義、ポインタに対する処理でメソッドを定義、ファイナライザを定義してデストラクタから呼出、というように記述する。
では、C#のクラスではどうか?以下に。
デストラクタ
・マネージリソースの解放:書かない
・アンマネージ(ネイティブ)リソースの解放:書く
ファイナライザ(引数なしDisposeメソッド)
・マネージリソースの解放:書く
・アンマネージ(ネイティブ)リソースの解放:書く
<参考>
Qiita:デストラクタとDisposeについて
Qiita:C# のファイナライザ、Dispose() メソッド、IDisposable インターフェースについて
IDisposable インターフェースの実装は、bool disposing を引数に持つDisposeメソッドをオーバーライドし、マネージリソースの解放は disposing が ture のときのみ実行するように記述し、デストラクタには Dispose (false) 、ファイナライザ(引数なしDisposeメソッド)には Dispose (true) で呼び出す記述をする。また、ファイナライザ(引数なしDisposeメソッド)には、明示的に引数なしDisposeメソッドを呼び出した場合等にガベージコレクタで二度目の呼び出しを行わないよう、GC.SuppressFinalize(this) を記述する。
<参考>
++C++; // 未確認飛行 C:Dispose にまつわる余談 - C# によるプログラミング入門
@IT:.NET TIPS - 確保したリソースを忘れずに解放するには?
ここまでの話は、using を使ってインスタンスを作成するクラスを継承する際にどうしたらよいかという疑問点から調べたものである。しかし、何でも継承するのではなく、委譲する(ラッパーを作成する)という選択肢も考えるべきのようだ。FileStream クラスのインスタンスを StreamReader クラス、StreamWriter クラスのコンストラクタに渡すと、読み、書きのどちらかに機能が決まるので、これも一種の委譲なのかもしれない。
<参考>
ikenox.info:継承と委譲の使い分けと、インターフェースの重要性について
Qiita:君の継承の使い方は間違っている
C++/CLIのクラスで、C++クラス(ネイティブコード)をラップする場合は、ネイティブコードのインスタンスを生成して代入するネイティブコードのポインタをメンバとして定義、ポインタに対する処理でメソッドを定義、ファイナライザを定義してデストラクタから呼出、というように記述する。
では、C#のクラスではどうか?以下に。
デストラクタ
・マネージリソースの解放:書かない
・アンマネージ(ネイティブ)リソースの解放:書く
ファイナライザ(引数なしDisposeメソッド)
・マネージリソースの解放:書く
・アンマネージ(ネイティブ)リソースの解放:書く
<参考>
Qiita:デストラクタとDisposeについて
Qiita:C# のファイナライザ、Dispose() メソッド、IDisposable インターフェースについて
IDisposable インターフェースの実装は、bool disposing を引数に持つDisposeメソッドをオーバーライドし、マネージリソースの解放は disposing が ture のときのみ実行するように記述し、デストラクタには Dispose (false) 、ファイナライザ(引数なしDisposeメソッド)には Dispose (true) で呼び出す記述をする。また、ファイナライザ(引数なしDisposeメソッド)には、明示的に引数なしDisposeメソッドを呼び出した場合等にガベージコレクタで二度目の呼び出しを行わないよう、GC.SuppressFinalize(this) を記述する。
<参考>
++C++; // 未確認飛行 C:Dispose にまつわる余談 - C# によるプログラミング入門
@IT:.NET TIPS - 確保したリソースを忘れずに解放するには?
ここまでの話は、using を使ってインスタンスを作成するクラスを継承する際にどうしたらよいかという疑問点から調べたものである。しかし、何でも継承するのではなく、委譲する(ラッパーを作成する)という選択肢も考えるべきのようだ。FileStream クラスのインスタンスを StreamReader クラス、StreamWriter クラスのコンストラクタに渡すと、読み、書きのどちらかに機能が決まるので、これも一種の委譲なのかもしれない。
<参考>
ikenox.info:継承と委譲の使い分けと、インターフェースの重要性について
Qiita:君の継承の使い方は間違っている