ildasm を実行して次のことがわかりました:
using(Simple simp = new Simple())
{
Console.WriteLine("here");
}
次と同等の IL コードを生成します。
Simple simp = new Simple();
try
{
Console.WriteLine("here");
}
finally
{
if(simp != null)
{
simp.Dispose();
}
}
問題は、なぜ finally で 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
}
ベストアンサー1
いいえ、finally ブロックは常に実行されます。オブジェクトは new から取得されるのではなく、オブジェクトを返す他の関数から取得される可能性があり、NULL が返される可能性があります。using() が役に立ちます。
dss539 さんは親切にも、彼のメモを載せることを提案してくれました:
using(Simple simp = null)
これは、展開時に最初に null をチェックする必要があるもう 1 つの理由です。