Nullable<T> and the ?? operator

Nullable value types

The concept of a null value is simple: it denotes the absence of a value. In the first version of C#, you could not have null value types. However, C# 2.0 introduced the Nullable<T> type to remedy this:

Nullable<int> nullInt = new Nullable<int>();
nullInt.HasValue;    // Returns false
nullInt.Value;       // Throws exception as no value has been set

Nullable<int> nonNullInt = new Nullable<int>(2);
nonNullInt.HasValue; // Returns true
nonNullInt.Value;    // Returns 2

You can also directly assign or retrieve the value:

Nullable<int> nullInt = null;
Nullable<double> nonNullDouble = 2.0;

Even better, appending the ? keyword to a type makes it a Nullable<T>:

int? nullInt = 2;         // Type is Nullable<int>
bool? nonNullBool = true; // Type is Nullable<bool>

Comparing nullable types also works as expected:

int? nullInt = null;
int? nonNullInt = 2;

nullInt == null;    // Returns true
nonNullInt == 2;    // Returns true
nonNullInt == null; // Returns false

The Nullable<T> class itself is implemented as a value type, so can we create a nullable Nullable<T>? Let’s try:

Nullable<Nullable<int>> nullableInception = null;

It turns out we can’t; the above code does not compile. This is due to the fact that the Nullable<T> struct does not allow nullable types to be specified as its generic type parameter (see MSDN).

The ?? operator

Besides adding Nullable<T>, C# 2.0 introduced another feature that deals with null values: the ?? operator (also known as the null-coalescing operator). It returns the left-hand operand if that is not null; otherwise it returns the right hand operand. This simple operator can greatly simplify your null checks:

public static string NullCheckWithIfStatement()
{
    if (str == null)
    {
        return string.Empty;    
    }

    return str;
}

public static string NullCheckWithTernaryOperator()
{
    return str == null ? string.Empty : str;
}

public static string NullCheckWithNullCoalescingOperator()
{
    return str ?? string.Empty;
}

The ?? operator manages to be both concise and very readable.

With more complex statements, the difference becomes even more striking:

public static string ComplexNullCheckWithIfStatement()
{
    string result1 = GetPotentiallyNullString1();

    if (result1 != null)
    {
        return result1;
    }

    string result2 = GetPotentiallyNullString2();

    if (result2 != null)
    {
        return result2;
    }

    return string.Empty;
}

public static string ComplexNullCheckWithNullCoalescingOperator()
{
    return GetPotentiallyNullString1() ??
           GetPotentiallyNullString2() ??
           string.Empty;
}

Of course, you can also use it on Nullable<T> values:

int? nullInt = null;
int? nonNullInt = 2;

nullInt ?? 8;    // Returns 8
nonNullInt ?? 5; // Returns 2

If you use the ?? operator to return a type’s default value, you can also use the GetValueOrDefault() method:

int? nullInt = null;
int? nonNullInt = 2;

nullInt.GetValueOrDefault();    // Returns 0
nullInt ?? default(int);        // Returns 0

nonNullInt.GetValueOrDefault(); // Returns 2
nonNullInt ?? default(int);     // Returns 2

Conclusion

Adding support for nullable value types was a very useful addition to C#. I use it often when dealing with databases, where nullable value types are common.

The ?? operator is a personal favorite of mine due to its conciseness and usefulness.