tags:

views:

134

answers:

3

Hi!

Basically, Nullable<T> is a structure, which explains things like calling .HasValue will never throw a NullReferenceException. I was wondering why - given a nullable which does not have a value - comparisons to null are always true, even when using Object.ReferenceEquals, which I thought would return false because it is a structure.

Is there special behaviour built into the CLR to make this possible? It would probably also explain why the generic struct constraint does not allow nullables.

Best Regards,
Oliver Hanappi

+17  A: 

If you do:

int? x = null;
if (x == null)

that will use HasValue.

Using Object.ReferenceEquals will box the value first - and that will convert the null value into a null reference (which is indeed special CLR behaviour). When a nullable value type is boxed, the result is either a null reference or a box of the underlying value type. In other words, there's no such thing as a boxed value of a nullable value type.

Jon Skeet
Thanks, the special boxing behaviour was the thing I have been looking for!
Oliver Hanappi
+4  A: 

Nullable comparisons do not always return true. Take this example, for instance:

int? n = null;
int? m = 5;

Console.WriteLine(n == null);  // prints True
Console.WriteLine(m == null);  // prints False

The CLR has special boxing behavior for Nullables, such that reference comparison works as you might expect. Essentially, the Value property of the struct is boxed into an object.

LBushkin
I suspect the OP was asking why it returns true for the null value across different ways of testing it - not when testing a non-null value.
Jon Skeet
@Jon Skeet: Yes, I suspected. But the question does possibly imply a behavior that isn't the case, which is why I chose to make that point.
LBushkin
In fact, I understood that question the same way as LBushkin., +1
Yossarian
Sorry for my unclear question, I actually just talked about nullables representing no value.
Oliver Hanappi
@Oliver Hanappi: No worries. I wasn't trying to be rude, I was just trying to point out that the way the question was written, it implied something that wasn't true. Since SO is used as a knowledge base by many users, it's helpful to the community to point out these kinds of issues.
LBushkin
Your "m" has a value, so it does not show anything.
macias
+1  A: 

Yes, Nullable<T> is a special struct that enjoys compiler support. I have blogged about what happens when it gets compiled into IL here.

Igor Zevaka