44

When I have a nullable long, for example, is there any difference between

myNullableLong.HasValue 

and

myNullableLong != null

... or is it just 'syntactic sugar'?

Fiona - myaccessible.website
  • 14,481
  • 16
  • 82
  • 117

3 Answers3

59

It's just syntactic sugar. They will behave exactly the same way - the nullity test actually gets compiled into a call to HasValue anyway.

Sample:

public class Test
{
    static void Main()
    {
        int? x = 0;
        bool y = x.HasValue;
        bool z = x != null;
    }
}

IL:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       25 (0x19)
  .maxstack  2
  .locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
  IL_0000:  ldloca.s   V_0
  IL_0002:  ldc.i4.0
  IL_0003:  call       instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
  IL_0008:  ldloca.s   V_0
  IL_000a:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
  IL_000f:  pop
  IL_0010:  ldloca.s   V_0
  IL_0012:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
  IL_0017:  pop
  IL_0018:  ret
} // end of method Test::Main
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Which of the two would you consider 'neater'? – Neil Knight Mar 08 '11 at 14:36
  • 2
    @Neil: It depends on the context. I would probably *usually* use the null comparison, but occasionally I guess `HasValue` would be more readable. – Jon Skeet Mar 08 '11 at 14:38
  • 2
    Thanks. I have to say that I see more `!= null` than I do `HasValue` comparisons. – Neil Knight Mar 08 '11 at 14:39
  • That's as I suspected. This question arose when I was asked in a code review to change my use of != null to HasValue, and I was questioning why... – Fiona - myaccessible.website Mar 08 '11 at 14:44
  • I know this is old, but was wondering the answer to this. I prefer `!= null` personally. I guess it would make sense though based on Jon's answer to prefer `HasValue` if `!= null` is compiled to a call to `HasValue` in any case, though, compilers are fast enough right... so it's basically a subjective choice. I'll stick to `!= null` personally :) – jamiebarrow Aug 15 '12 at 10:38
  • 1
    I wonder if this holds true in Linq-To-Entities. I can see how it could equate these two when explicitly comparing to null, but what about comparing two nullable field like so: `Where( x => true && (x.t1.NullableField == x.t2.NullableField)). In TSQL, such a comparison would fail if both fields are null, unless it explicitly injects an 'or both are null' check. – Triynko Sep 10 '15 at 18:30
8

It's syntactic sugar; Nullable<T> is actually a struct, so it cannot actually be null; the compiler turns calls that compare to null (like your second example) into calls to HasValue.

Note, though, that boxing a Nullable<T> into an object will result in either the value of T (if it has a value) or null (if it doesn't).

I.E.

int? foo = 10; // Nullable<int> with a value of 10 and HasValue = true
int? bar = null; // Nullable<int> with a value of 0 and HasValue = false

object fooObj = foo; // boxes the int 10
object barObj = bar; // boxes null

Console.WriteLine(fooObj.GetType()) // System.Int32
Console.WriteLine(barObj.GetType()) // NullReferenceException
Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
3

No.

The C# compiler has built-in support for Nullable<T> and will turn equality operations involving null into calls to the struct's members.

n != null and n.HasValue will both compile to identical IL.

Julien Poulin
  • 12,737
  • 10
  • 51
  • 76
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964