Search code examples
c#ildasm

Objects based on nullable types are only boxed if the object is non-null


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?


Solution

  • 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).