Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

IDisposableなインスタンスをオブジェクト初期化子で初期化するとコード分析でCA2000を警告される

More than 5 years have passed since last update.

CA2000とは

('ω')<CA2000: スコープが失われる前にオブジェクトを破棄します

コード分析の規則セットでは、Microsoftのすべての規則を選択した場合のみ有効になるようです。

問題

次のようなクラスを定義し、Mainメソッドで初期化してDisposeします。

// MyClass
class MyClass : IDisposable
{
    public string Text { get; set; }
    public void Dispose( ) { return; }
}
// Program クラス内
static void Main( string[ ] args )
{
    var value = new MyClass( )
    {
        Text = "",
    };
    value.Dispose( );
}

このコードに対する CA2000 のメッセージは次の通りです。

CA2000  スコープを失う前にオブジェクトを破棄  メソッド 'Program.Main(string[])' で、オブジェクト '<>g__initLocal0' が破棄されない例外パスがあります。オブジェクト '<>g__initLocal0' への参照がすべてスコープ外になる前に、このオブジェクトの System.IDisposable.Dispose を呼び出してください。  ConsoleApplication1 Program.cs  13

原因

MyClassTextプロパティで例外が発生する可能性が有ると判断されたためです。
オブジェクト初期化子では、プロパティへの設定が失敗すると参照がvalueに代入されないため、
MyClassのインスタンスをDisposeする手段が無くなってしまいます。 usingも無視されます。

詳しくはオブジェクト初期化子の罠を参照して下さい。

対策

IDisposable なインスタンスの初期化では、オブジェクト初期化子を使用しないようにします。

// Program クラス内
static void Main( string[ ] args )
{
    var value = new MyClass( );
    try
    {
        value.Text = "";
    }
    finally
    {
        value.Dispose( );
    }
}
kuchikios
✌('ω')✌
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away