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 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.