How is it possible for me to call HasValue on a null object?

Consider the following code:

int? myInt = null;
var hasValue = myInt.HasValue;

This is perfectly acceptable, and HasValue will return false. But how have I managed to reference a property on an object that is null? The following wouldn't work:

public class MyClass
{
    public bool MyBool { get { return true; } };
}

// Elsewhere in code...
MyClass myObject = null;
myObject.MyBool;

This would raise a null reference exception. The fact I'm comparing the two code snippets above as though they are equal tells me that I'm misunderstanding a structure or some syntax somewhere.

Can somebody please tell me why code snippet 1 does not raise an exception, but why my code snippet 2 would?

Jon Skeet
people
quotationmark

In the first case, you have a value of type Nullable<int>, which is "the null value for the type". The Nullable<T> type is a value type with two fields, like this:

public struct Nullable<T> where T : struct
{
    private T value;
    private bool hasValue;
}

When you use the null literal with a Nullable<T>, you're really just creating a value where the value field has the default value of T, and hasValue is false. Using the HasValue property isn't following a reference - it's just getting a field out of the struct.

In the second case, the value of myObject is a null reference... so if you try to use the MyBool property, that fails because it's trying to find an object when there isn't one.

So the key points are:

  • Nullable<T> is a struct, not a class
  • The value of a variable of type Nullable<T> is just a value with two fields, not a reference
  • The null literal just means "the null value of the relevant type", it does not always mean a null reference.

people

See more on this question at Stackoverflow