I have created a simple C#
program:
class Program
{
static void Main(string[] args)
{
Int32? a = null;
object x = a;
}
}
According to MSDN:
Objects based on nullable types are only boxed if the object is non-null. If HasValue is false, the object reference is assigned to null instead of boxing.
I have tried my executable in ILDASM
and spotted that IL
code has box method called.
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 17 (0x11)
.maxstack 1
.locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> a,
[1] object x)
IL_0000: nop
IL_0001: ldloca.s a
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0009: ldloc.0
IL_000a: box valuetype [mscorlib]System.Nullable`1<int32>
IL_000f: stloc.1
IL_0010: ret
} // end of method Program::Main
My question is: Why it was called? Maybe I am doing something wrong or misunderstand something?
The attempt to box a value does not mean it actually is a boxed value - x
will be null
, not a boxed null
. I think the MSDN is trying to explain that:
Int32? a = null;
object x = a;
object y = a;
object.ReferenceEquals(x, y); // true
But:
Int32? a = 3;
object x = a;
object y = a;
object.ReferenceEquals(x, y); // false
As for compiling in release mode - it might not attempt to box the value because at compile time it is known that a
is null
- if a
was a parameter of a public method, it will probably always attempt to box the value (but never actually box null
).