26

これを見つけるためにildasmを実行しました:

    using(Simple simp = new Simple())
    {
        Console.WriteLine("here");
    }

これと同等の IL コードを生成します。

    Simple simp = new Simple();
    try
    {
        Console.WriteLine("here");
    }
    finally
    {
        if(simp != null)
        {
            simp.Dispose();
        }
    }

問題は、なぜ最終的に null をチェックするのかということです。finally ブロックは、try ブロックが実行された場合にのみ実行され、try ブロックは、Simple コンストラクターが成功した場合 (つまり、例外がスローされない場合) にのみ実行されます。この場合、simp は非 null になります。(Simple コンストラクターと try ブロックの先頭の間に何らかのステップが介在するのではないかという懸念がある場合、それは本当に問題になります。例外がスローされて、finally ブロックの実行がまったく妨げられる可能性があるからです。)それで、なぜ一体?

using ステートメントが try-finally よりも優れているかどうかの議論は (お願いします) 脇に置いて、try-finally ブロックを次のように記述します。

    Simple simp = new Simple();
    try
    {
        Console.WriteLine("here");
    }
    finally
    {
        simp.Dispose();
        simp = null;        // sanity-check in case I touch simp again
                            // because I don't rely on all classes
                            // necessarily throwing
                            // ObjectDisposedException
    }
4

5 に答える 5

22

いいえ、finally ブロックは常に実行されます。new からオブジェクトを取得するのではなく、オブジェクトを返す他の関数からオブジェクトを取得している可能性があります - そしてそれは NULL を返すかもしれません。using() はあなたの友達です!

dss539 は親切にも、彼のメモを含めることを提案してくれました:

using(Simple simp = null) 

展開が最初に null をチェックしなければならないもう 1 つの理由です。

于 2009-06-03T20:25:13.553 に答える
11

using(Simple simp = null)拡張が最初にnullをチェックしなければならないもう1つの理由です。

于 2009-06-03T20:31:15.833 に答える
4

using ステートメントに関するMSDN 。

私が奇妙だと思うのは、次のように展開されないことです。

Simple simp = new Simple();
Simple __compilergeneratedtmpname = simp;
try
{
    Console.WriteLine("here");
}
finally
{
    if(__compilergeneratedtmpname != null)
    {
        __compilergeneratedtmpname.Dispose();
    }
}
于 2009-06-03T21:04:33.113 に答える
2

あなたのコメントのようです:

「Simple コンストラクターと try ブロックの先頭の間に何らかのステップが介在するのではないかという懸念がある場合、それは本当に問題です。例外がスローされて、finally ブロックの実行がまったく妨げられる可能性があるからです。」

死んでいる可能性があります。見る:

原子性と非同期例外の失敗

また、WCF と使用に関する問題にも注意したいと思います。

以下を参照するステートメントと WCF サービス プロキシの使用に関する問題の回避:

Using ステートメントに関する問題の回避

于 2010-03-23T15:26:01.560 に答える