7.12 The Null Coalescing Operator

A null coalescing expression of the form a ?? b requires a to be of a nullable type or reference type. If a is non-null, the result of a ?? b is a; otherwise, the result is b. The operation evaluates b only if a is null.

The null coalescing operator is right-associative, meaning that operations are grouped from right to left. For example, an expression of the form a ?? b ?? c is evaluated as a ?? (b ?? c). In general terms, an expression of the form E1 ?? E2 ?? ... ?? EN returns the first of the operands that is non-null, or null if all operands are null.

The type of the expression a ?? b depends on which implicit conversions are available between the types of the operands. In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a, B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. Specifically, a ?? b is processed as follows:

If A is not a nullable type or a reference type, a compile-time error occurs.

If A is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At runtime, a is evaluated first. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.

Otherwise, if an implicit conversion exists from b to A, the result type is A. At runtime, a is evaluated first. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.

Otherwise, if b has a type B and an implicit conversion exists from A0 to B, the result type is B. At runtime, a is evaluated first. If a is not null, a is unwrapped to type A0 (unless A and A0 are the same type) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.

Otherwise, a and b are incompatible, and a compile-time error occurs.

ERIC LIPPERT

These conversion rules considerably complicate the transformation of a null coalescing operator into an expression tree. In some cases, the compiler must emit an additional expression tree lambda specifically to handle the conversion logic.

CHRIS SELLS

The ?? operator is useful for setting default values for reference types or nullable value types. For example,

When I first saw the new ?? operator in C# 2.0, I was a bit skeptical. Did we really need another terse operator to further obfuscate our code? Over the last year or two, however, I’ve actually found myself using it quite a bit, and I think this operator actually enhances readability once you get used to it. So I guess the answer was yes, we—or I, at least—did need the ?? operator.

Consider the example of implementing a property that is backed by ViewState in ASP. NET (say, for a custom control):