In this article, we are going to find out what null-coalescing operator ?? and null-coalescing assignment ??= operators are and how to use them.

To download the source code for this article, you can visit our GitHub repository.

Let’s dive in!

Null-Coalescing Operator in C#

The null-coalescing operator is a C# operator consisting of two question marks ??. The usage of the ?? operator allows for checking if the value of a given variable is null and if yes, we can return a default value instead. 

Let’s try to explain it with a simple example.

Imagine, we have two variables: userInput, which stores data collected from a user, and defaultValue. In the expression userInput ?? defaultValue, if userInput is not null, then the result is userInput, otherwise, the result is defaultValue. The defaultValue variable is evaluated only if userInput doesn’t have value.

Let’s see how we could code this behavior without the usage of the null-coalescing operator.

For that purpose, we will create a method that calculates the yearly income:

public int CalculateYearlyIncome(int monthlyIncome, int numberOfMonths, int? extraBonus = null)
{
    if (extraBonus == null)
        return (monthlyIncome * numberOfMonths) + 0;
    else
        return (monthlyIncome * numberOfMonths) + extraBonus.Value;
}

Alternatively, we could write this with the usage of the ternary operator:

public int CalculateYearlyIncome(int monthlyIncome, int numberOfMonths, int? extraBonus = null)
{
    var bonus = extraBonus != null ? extraBonus.Value : 0
  
    return (monthlyIncome * numberOfMonths) + bonus;
}

Already better than the first option, but with the usage of the ?? operator, we can rewrite this method in an even shorter and simpler way:

public int CalculateYearlyIncome(int monthlyIncome, int numberOfMonths, int? extraBonus = null)
{
    return monthlyIncome * numberOfMonths + (extraBonus ?? 0);
}

Looks much cleaner now.

Null-Coalescing Assignment Operator in C#

Now that we know the ?? operator, understanding the null-coalescing assignment operator should be quite simple to explain.

Thanks to the ??= operator we can check if a given variable is null, and if so, we can assign a different value to it.

Let’s have a look at how to use it in practice.

This time we want to calculate monthly income, based on the hourly wage and number of working hours in the month. Both parameters are of type int?. If null happens, we want to take the average values for both variables:

public int CalculateMonthlyIncome(int? hourlyWage, int? numberOfHours)
{
    if (hourlyWage == null)
        hourlyWage = 15;

    if (numberOfHours == null)
        numberOfHours = 168;

    return hourlyWage.Value * numberOfHours.Value;
}

The usage of the null-coalescing assignment operator allows us to make the method shorter and cleaner:

public int CalculateMonthlyIncome(int? hourlyWage, int? numberOfHours)
{
    hourlyWage ??= 15;
    numberOfHours ??= 168;
 
    return hourlyWage.Value * numberOfHours.Value;
}

Again the code is more concise and cleaner.

Null-Coalescing Operators’ Associativity

The null-coalescing and null-coalescing assignment operators are right-associative. In other words, they are evaluated in order from right to left.

What does it actually mean and how can we use this?

Imagine, we want to evaluate yearly income based on average quarterly earnings. Of course, we would like to calculate it based on the most recent data. The problem is that for some reason, we don’t always have up-to-date values. In that case, we want to calculate it based on one of two previous quarters (but of course, we always want to have the most recent data):

currentQuarter ?? pastQuarter1 ?? pastQuarter2

Under the hood, the expression is evaluated to:

currentQuarter ?? (pastQuarter1 ?? pastQuarter2)

We check if we have data for the current quarter, if not – we check the previous quarter, and if it is also a null, we check even earlier quarter.

Of course, we can create such expressions for as many parameters as we want. As a result, we will always receive the first non-null value. 

How Do We Use Null Coalesce in C#?

As we have seen in the previous examples, in cases where a variable can be null or an expression can return a null operator ?? allows us to assign a default value or evaluate another expression.

Another interesting application can be a validation process.

Imagine, we don’t want to assign any default value, and null prevents the operation from being properly performed. In this case, by using the ?? operator we can check if a variable has a value and throw an exception if it doesn’t.

Let’s go back to calculating monthly income:

public int CalculateMonthlyIncome(int? hourlyWage, int? numberOfHours)
{
    hourlyWage = hourlyWage ?? throw new ArgumentNullException(nameof(hourlyWage), $"Null value is not allowed");
    numberOfHours ??= 168;
    
    return hourlyWage.Value * numberOfHours.Value;
}

While the default value for the number of working hours per month makes sense, using the average salary may be quite inaccurate. So, when hourlyWage is null we throw an exception to let the user know that he needs to provide a valid value.

Conclusion

In this article, we have covered the null-coalescing and the null-coalescing assignment operators and the ways to use them.