Nullable Types

Nullable Types

In the previous code, a reference type is set to null. Assigning a null to an object indicates that it is unused. This is consistent for all reference types. Can you similarly flag an integer as unused? Nulls are not assignable to primitive value types. (It would cause a compiler error.)

int variablea=null;

Setting an integer to -1 is a possible solution, assuming that this value is outside the set of expected values. However, this is a proprietary solution; it requires explicit documenting and is not very extensible. A consistent solution is required for all integers and indeed for all value types.

Nullable types are a consistent solution for determining whether a value object is empty. Declare a nullable type by adding the ? type modifier in a value type declaration. Here is an example:

double? variable1=null;

The object variable1 is a nullable type and the underlying type is double. A nullable type extends the interface of the underlying type with the HasValue and Value properties. Both properties are public and read-only. HasValue is a Boolean property, whereas the type of Value is the same as the underlying type. If the nullable type is assigned a non-null value, HasValue is true and the Value property is accessible. Otherwise, HasValue is false, and an exception is raised if the Value property is accessed. The acceptable range of values for a nullable type includes the null value and the extents of the underlying type.

Set the default value of a nullable type with the null coalescing operator. The operator is ??. The default value must be the same type as the underlying type. The default value is returned if the nullable type is null—otherwise empty. This code sets the default value for variablea to zero. Otherwise, variable2 is assigned the value of variable1:

double variable2=variable1??0;

This code demonstrates nullable types:

static void Main() {
    int? variablea=null;
    Console.WriteLine(variablea.HasValue); // false
    int variableb=variablea??5;
    Console.WriteLine(variableb); // 5