もくじ
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f
やりたいこと
ファイルの読み書きをするときによく書いている下記のようなコードで、コード分析をかけたときにいつもCA2202
という警告が出てきてたが、「実績あるコード」ということで修正せずに今まで来ていた。
が、新規ソフトでも同じ警告が出たので、この際直し方をはっきりさせておきたい。
byte[] data = { 0, 1, 2, 3 };
using (var fs = new FileStream(@"C:\work\file1.data", FileMode.Create))
using (var bw = new BinaryWriter(fs))
{
bw.Write(data);
}
なおしかた
下記のようなコードに直す。
byte[] data = { 0, 1, 2, 3 };
FileStream fs = null;
try
{
fs = new FileStream(@"C:\work\file1.data", FileMode.Create);
using (var bw = new BinaryWriter(fs))
{
fs = null;
bw.Write(data);
}
}
finally
{
fs?.Dispose();
}
ポイント
using (var bw = new BinaryWriter(fs))
の中で、使い終わったfsを、冒頭でfs = null;
すること。
この一文を書かないと、やはりCA2202が出てしまう。
備考
usingで、使い終わったFileStreamのオブジェクトfsが、
- BinaryWriterのオブジェクトbwが破棄Dispose)されるとき
- 自分のusingで、自動でDisposeされるとき
の2回、破棄される可能性がある、作りによっては二回目の破棄の際にアプリ落ちますよ、という警告。
実際はこのコードではアプリが落ちたりはしない(おそらく、FileStreamとかBinaryWriterが、すでに破棄済みのものは二重に破棄しないようにつくってくれてるから)が、IDisposableを実装したなにかのライブラリとか、自前のクラスを使うときにusingでこういうことを書くと、Disposeの実装の仕方によっては落ちてしまうものと思われる。
参考
CA2202: Do not dispose objects multiple times
公式の?対処方法がここに書かれている。
https://docs.microsoft.com/ja-jp/visualstudio/code-quality/ca2202-do-not-dispose-objects-multiple-times?view=vs-2019
入れ子の using に対する CA2202 違反の解決策について
https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/eb99475a-e97c-48f5-90fc-029331025e6f/20837124282337612398-using-12395235501237712427-ca2202?forum=netfxgeneralja