C# Double Question Mark Operator (??)

A thumbnail showing code. Everything you need to know about C# double question mark operator.

If you are C# developer, you probably came across the double question mark operator ??.

But what is it? How to use it?

The C# double question mark operator (??) provides a way to handle null values in a more concise and elegant way than the traditional if/else statement.

The null coalescing operator was added to C# in version 2.0 along with nullable value types.

In this blog post, we will discuss what the C# double question mark operator is, and how to use it in your own code.

C# Double question mark operator example.
Because the `shipDate` is `null`, the `shipOn` gets assigned DateTime.MaxValue.

What is null coalescing operator?

The C# double question mark operator ?? is known as the null coalescing operator.

In a nutshell, the null coalescing operator is "if the first value is null, use this other value."

Null coalescing operator is a binary operator that takes two operands: the first operand is an expression that can be null, and the second operand is the value that you want to assign to the expression if it is not null.

  • Null coalescing operator is a useful way to provide default value for a variable.

The null coalescing operator can be chained. Which means it will return the first non-null variable in the chain:

csharp
int? first = null;
int? second = null;
int? third = 5;

Console.WriteLine(first ?? second ?? third); // 5

Note that everything to the right of ?? is only calculated if left is null. So a ?? M() only calls M() if a is null, similar to || and &&.

C# Non-nullable value type

If the value is non-nullable type, the compiler will throw an error. For example, if we try to do it with an int

Operator '??' cannot be applied to operands of type 'int' and 'int'

Besides the compiler error, it also doesn't make much sense to use it with the non-nullable value type.

Left-hand operand and the right-hand operand

A new ??= null-coalescing operator was added in C# 8. This operator assigns the value of its right operand to the left operand only if the left operand is a null value.

Left hand operand needs to be of nullable type. Otherwise, a compile-time error will occur.

csharp
using System;

public class Program
{
	public static void Main()
	{
		int? first = null;
		int? second = null;

		if (!first.HasValue)
		{
			first = 5;
		}
		Console.WriteLine(first); // 5

		second ??= 5;
		Console.WriteLine(second); // 5
	}
}

In the above example, the two-question marks-equals ??= makes it much easier to assign a value if the left-hand operand evaluates to null.

Examples

The following examples illustrate how the C# null coalescing operator can be used:

Throw an exception

You can use a throw expression as the right-hand operand of the ?? operator.

For example, if you are using dependency injection for your classes, you may have a class that depends on an ILogger interface. If the logger is not correctly injected, your service should throw an exception:

csharp
 public VideoService(ILogger<VideoService> logger)
        {
            _logger = logger ??  throw new ArgumentNullException(nameof(logger), "Logger cannot be null");

        }

Default value

The double question mark operator can also be used to provide a default value for a nullable type.

csharp
	public void FetchResults(int? numberOfResults)
	{
		int defaultNumber = 5;
		GetResults(numberOfResults ?? defaultNumber); // If the value is not passed, defaults to defaultNumber.
	}

DateTime example

csharp
using System;
public class Program {
    public static void Main() {
        DateTime? shipDate = null;
		Console.WriteLine(shipDate ?? DateTime.MaxValue); // Defaults to 12/31/9999 11:59:59 PM in case `shipDate` is null.
    }
}

Often when designing APIs, old systems cannot handle null values for the Date, so using the null coalescing operator to default to MaxValue or MinValue is a nice workaround.

Conclusion

The C# double question mark operator is a useful tool that can help you to handle null values in a more concise and elegant way.

It makes code well-organized and readable.

If the left operand of the operator is not null, then the operator will return the left operand; otherwise, it will return the right operand.

Use null coalescing operator when:

  • Working with nullable types to prevent NullReferenceException
  • Providing a default value for a variable.
  • Throwing an argument exception to prevent null values.
  • Chaining null-checks.

Remember, the operator can only be used with non-nullable value type variables. If the left-hand operand is not a nullable type, you will get a compile-time error.

Published on