Could someone please explain to me why the code shown below is valid in C# and executes the call to Console.WriteLine
?
using (null)
{
Console.WriteLine ("something is here")
}
It compiles into (finally block is shown). As you can see compiler decides not to execute the Dispose()
method and jumps to the endfinally
instruction.
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
However, if I run the following code, it will fail with a NullReferenceException
(which is expected):
((IDisposable)null).Dispose();
IL_0023: ldnull
IL_0024: callvirt instance void [mscorlib]System.IDisposable::Dispose()
Why does the first version compile? Why does the compiler decide not to execute Dispose()
? Are there any other cases when compiler may decide not to call Dispose()
in a using
block?