I always used (a) Nullable<>.HasValue
because I liked the semantics. However, recently I was working on someone else's existing code base where they used (b) Nullable<> != null
exclusively instead. Is there a reason to use one over the other, or is it purely preference?
(a)
int? a;
if (a.HasValue)
...
(b)
int? b;
if (b != null)
...
In VB.Net. Do NOT use "IsNot Nothing" when you can use ".HasValue". I just solved an "Operation could destabilize the runtime" Medium trust error by replacing "IsNot Nothing" with ".HasValue" In one spot. I don't really understand why, but something is happening differently in the compiler. I would assume that "!= null" in C# may have the same issue.
The compiler replaces null comparisons with a call to
HasValue
, so there is no real difference. Just do whichever is more readable/makes more sense to you and your colleagues.I did some research on this by using different methods to assign values to a nullable int. Here is what happened when I did various things. Should clarify what's going on. Keep in mind:
Nullable<something>
or the shorthandsomething?
is a struct for which the compiler seems to be doing a lot of work to let us use with null as if it were a class.As you'll see below,
SomeNullable == null
andSomeNullable.HasValue
will always return an expected true or false. Although not demonstrated below,SomeNullable == 3
is valid too (assuming SomeNullable is anint?
).While
SomeNullable.Value
gets us a runtime error if we assignednull
toSomeNullable
. This is in fact the only case where nullables could cause us a problem, thanks to a combination of overloaded operators, overloadedobject.Equals(obj)
method, and compiler optimization and monkey business.Here is a description of some code I ran, and what output it produced in labels:
Ok, lets try the next initialization method:
All the same as before. Keep in mind that initializing with
int? val = new int?(null);
, with null passed to the constructor, would have produced a COMPILE time error, since the nullable object's VALUE is NOT nullable. It is only the wrapper object itself that can equal null.Likewise, we would get a compile time error from:
not to mention that
val.Value
is a read-only property anyway, meaning we can't even use something like:but again, polymorphous overloaded implicit conversion operators let us do:
No need to worry about polysomthing whatchamacallits though, so long as it works right? :)
If you use linq and want to keep your code short, I recommand to always use
!=null
And this is why:
Let imagine we have some class
Foo
with a nullable double variableSomeDouble
If somewhere in our code we want to get all Foo with a non null SomeDouble values from a collection of Foo (assuming some foos in the collection can be null too), we end up with at least three way to write our function (if we use C# 6) :
And in this kind of situation I recommand to always go for the shorter one
I prefer
(a != null)
so that the syntax matches reference types.General answer and rule of thumb: if you have an option (e.g. writing custom serializers) to process Nullable in different pipeline than
object
- and use their specific properties - do it and use Nullable specific properties. So from consistent thinking point of viewHasValue
should be preferred. Consistent thinking can help you to write better code do not spending too much time in details. E.g. there second method will be many times more effective (mostly because of compilers inlining and boxing but still numbers are very expressive):Benchmark test:
Benchmark code:
https://github.com/dotnet/BenchmarkDotNet was used
PS. People say that advice "prefer HasValue because of consistent thinking" is not related and useless. Can you predict the performance of this?
PPS People continue minus but nobody tries to predict performance of
CheckNullableGenericImpl
. And there compiler will not help you replacing!=null
withHasValue
.HasValue
should be used directly if you are interested in performance.