LoginSignup
5
1

More than 3 years have passed since last update.

[C#] 2つのIDisposableをusingしたときのコード分析の指摘CA2202の対応

Posted at

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

ファイルの読み書きをするときによく書いている下記のようなコードで、コード分析をかけたときにいつもCA2202という警告が出てきてたが、「実績あるコード」ということで修正せずに今まで来ていた。
が、新規ソフトでも同じ警告が出たので、この際直し方をはっきりさせておきたい。

CA2202でるコード.cs
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);
}

出る警告
image.png

なおしかた

下記のようなコードに直す。

CA2202でないコード.cs
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

5
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1