C#オブジェクトの破棄を保証する

スポンサーリンク

プログラム中で、アンマネージ リソースなどを扱う場合はリソースを解放する必要があります。破棄には Dispose メソッド、Close メソッドがある場合は Close メソッドを使用します。必要なくなった時点で破棄すれば良いわけですが、何らかの原因で例外が発生した場合を考えると安易に実装できません。ここでは、オブジェクトの破棄を保証するための方法を紹介します。

サンプルコード

以下にサンプルコードを示します。

最初に Dispose メソッドだけが用意されている場合の例です。C# では using ステートメントを使用することで、オブジェクトが破棄されるスコープを定義することが可能です。using ステートメントの末尾に到達したか、例外がスローされたなどの理由で、制御がステートメント ブロックを離れたときに破棄されます。ただし、対象となるオブジェクトは IDisposable インターフェイスが実装されている必要があります。これは、using ステートメントのブロックを抜けた時点で呼び出すのが、IDisposable.Dispose を実装しているメソッドだからです。

C# 全般
    // cForm1 が破棄されることを保証するために using を使用する
    using (Form1 cForm1 = new Form1()) {
        cForm1.ShowDialog();
    }
    // using ステートメントを抜けた時点で自動で破棄される

次に Connection 系などに多い、Close メソッド、Dispose メソッドの双方が実装されている場合の例です。Open メソッドに対して Close メソッドがあるため、Open メソッドの後で Finally を実装することになります。もちろん、Connection 以外に Command、DataAdapter、DataReader などを使用した場合は中でネストすることになります。(ここでは説明を省いています) C# では using ステートメントで Dispose メソッドが実行されることを保証し、try ~ finally で Close メソッドが実行されることを保証します。

C# 全般
    // cSqlConnection が破棄されることを保証するために using を使用する
    using (System.Data.SqlClient.SqlConnection cSqlConnection = new System.Data.SqlClient.SqlConnection("...省略...")) {
        cSqlConnection.Open();

        // cSqlConnection が閉じられることを保証するために try ~ finally を使用する
        try {
            //
            // ここで cSqlConnection を使用する
            //
        } finally {
            // cSqlConnection を閉じる
            if (cSqlConnection != null) {
                cSqlConnection.Close();
            }
        }
    }
    // using ステートメントを抜けた時点で自動で破棄される

次に Stream 系などに多い、Close メソッド、Dispose メソッドの双方が実装されているものの、Dispose メソッドが Protected などで隠蔽化されている場合の例です。C# は変わりありません。もともと using ステートメントは、IDisposable.Dispose メソッドを実装した内部の Dispose メソッドを呼び出します。

C# 全般
    // cReader が破棄されることを保証するために using を使用する
    using (System.IO.StreamReader cReader =
        new System.IO.StreamReader(@"C:\Hoge.txt", System.Text.Encoding.Default)) {

        // cReader が閉じられることを保証するために try ~ finally を使用する
        try {
            //
            // ここで cReader を使用する
            //
        } finally {
            // cReader を閉じる
            if (cReader != null) {
                cReader.Close();
            }
        }
    }
    // using ステートメントを抜けた時点で自動で破棄される

関連するリファレンス

準備中です。

スポンサーリンク