请问为什么下面展示的代码在C#中是合法的,并且可以执行对Console.WriteLine
的调用?
using (null)
{
Console.WriteLine ("something is here")
}
它编译成(最终块显示)。正如你所看到的,编译器决定不执行Dispose()
方法并跳转到endfinally
指令。
IL_0013: ldnull
IL_0014: ceq
IL_0016: stloc.1
IL_0017: ldloc.1
IL_0018: brtrue.s IL_0021 // branches here and decide not to execute Dispose()
IL_001a: ldnull
IL_001b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0020: nop
IL_0021: endfinally
然而,如果我运行以下代码,它将会产生一个 NullReferenceException
(这是预料之中的):
((IDisposable)null).Dispose();
IL_0023: ldnull
IL_0024: callvirt instance void [mscorlib]System.IDisposable::Dispose()
为什么第一个版本编译通过?为什么编译器决定不执行“Dispose()
”?是否还有其他情况下编译器可能在using
块中决定不调用Dispose()
?