Search code examples
c#structnullcompile-time-constant

How does the C# visual studio compiler treat struct/NULL comparisons?


We just ran across some bad code like this in our c#.net 4 codebase

DateTime myDate = someValue;
If (myDate==Null)
    Do Something

It occurred to us that this condition will never occur.

How does the compiler handle these non-nullable struct comparisons?

Originally we were surprised that it would compile... but rationalized it on the point that you could certainly have a constant comparison like:

If(1==2)

Which would also never resolve true... but in that case the compiler can easily tell they are constants. Does it optimize or rollup non-nullable comparisons?


Solution

  • I punched this into LinqPad:

    var t = new DateTime();
    t.Dump();
    (t == null).Dump();
    

    And got this:

    IL_0000:  ldloca.s    00 
    IL_0002:  initobj     System.DateTime
    IL_0008:  ldloc.0     
    IL_0009:  call        LINQPad.Extensions.Dump
    IL_000E:  pop         
    IL_000F:  ldc.i4.0    
    IL_0010:  call        LINQPad.Extensions.Dump
    

    So yes, the compiler compiles it to the same as:

    var t = new DateTime();
    t.Dump();
    (false).Dump();
    

    Interestingly, if I create my own struct (TestStruct) and try this:

    TestStruct t;
    (t == null).Dump();
    

    ... the compiler complains that I can't do an equals comparison between TestSruct and null.

    Update

    In a comment, Paolo points to another StackOverflow post reporting this last phenomenon. Apparently by overloading the == and != operators, a value type becomes subject to an automatic conversion from t == null to (Nullable<TestClass>)t == (Nullable<TestClass>)null. If you haven't overloaded those operators, this implicit conversion doesn't make sense, so you get an error.