Home > Articles > Programming > C#

Using Expressions in C#

  • Print
  • + Share This
The authors of The C# Programming Language, along with colleagues Eric Lippert, Chris Sells, Fritz Onion, Joseph Albahari, and Don Box, discuss expressions in C#, including anonymous function expressions and query expressions.
This chapter is from the book

7.12 The Null Coalescing Operator

The ?? operator is called the null coalescing operator.

   null-coalescing-expression:
     conditional-or-expression
     conditional-or-expression ?? null-coalescing-expression

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.
  • + Share This
  • 🔖 Save To Your Account