要約
- Reader/Writer にも Dispose がある
- 基本的に Reader/Writer の方の Dispose だけを呼べばOK
- Close メソッドは呼ばなくてよい。(中で Dispose を読んでいるだけ)
- Dispose を直接書くより、 using 構文を使うのが良い
きっかけ
C#でストリームを扱うときは
- C# の Stream クラス の読み書きは Reader/Writer でする
- Stream クラスは使い終わったら Dispose する
- Reader/Writer も Dispose する必要がある
という感じですが、このあたりでいくつか気になる点があったので調べました。
なぜ Reader/Writer にも Dispose が存在するのか
ストリームは内部にファイルポインタなり、ソケットなどを持っているだろうから、Dispose必要というのはわかる。
では、Reader/Writer にもDisposeがあるのはなぜ?(何を解放しているのか?)
TextReader の場合
StreamReader の親である TextReader は何もしなくていいみたいで、空のメソッド。
protected virtual void Dispose(bool disposing)
{
}
StreamReader の場合
StreamReader になると、エンコーディングやバッファの情報を消している
if (!LeaveOpen && (_stream != null))
{
_stream = null;
_encoding = null;
_decoder = null;
_byteBuffer = null;
_charBuffer = null;
_charPos = 0;
_charLen = 0;
base.Dispose(disposing);
}
なるほど!読み書きのバッファなどを持っている場合、それも解放しないといけないってことですかね。
Reader/Writer の Dispose と Stream の Dispose 両方呼ぶ必要があるか
Reader/Writer の方だけでいいみたいです。
中のStreamも自動的にDisposeしてくれます。
ただし、Reader/Writer のコンストラクタ引数の leaveOpen を true にすることで、 Stream を解放しないようにもできます。
Close メソッドとは何なのか
内部で Dispose を呼び出しているだけなので、無視して大丈夫です。
using 構文について
usingで囲むと自分でDisposeを呼ぶ必要はなくなります。(using構文が内部でDisposeを呼んでくれます)
積極的に using で済ますようにしたほうが良さそうです。
using (var stream = ...)
using (var reader = new StreamReader(stream, ...))
{
...
}
// usingを抜けたら自動的に Dispose してくれる
(Marimoiroさんコメントありがとうございます)
参考リンク
参考リンク