Nullables

Returning to the distinction between value and reference types, a value type stores its value directly in the variable, while a reference type stores an address to another location in memory that has been allocated to hold the value. This is why reference types can be null - this indicates they aren’t pointing at anything. In contrast, value types cannot be null - they always contain a value. However, there are times it would be convenient to have a value type be allowed to be null.

For these circumstances, we can use the Nullable<T> generic type, which allows the variable to represent the same values as before, plus null. It does this by wrapping the value in a simple structure that stores the value in its Value property, and also has a boolean property for HasValue. More importantly, it supports explicit casting into the template type, so we can still use it in expressions, i.e.:

Nullable<int> a = 5;
int b = 6;
int c = (int)a + b;
// This evaluates to 11.

However, if the value is null, we’ll get an InvalidOperationException with the message “Nullable object must have a value”.

There is also syntactic sugar for declaring nullable types. We can follow the type with a question mark (?), i.e.:

int? a = 5;

Which works the same as Nullable<int> a = 5;, but is less typing.