4

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?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Matthew
  • 10,244
  • 5
  • 49
  • 104

1 Answers1

7

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.

Community
  • 1
  • 1
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315