Null checking is an essential part of developing quality C# code. If code attempts to access a member of a null object reference, it throws a NullReferenceException
. However, using if
statements to check for null references can make the code more verbose.
The null-coalescing and null-conditional operators can reduce the amount of code that needs to be written to avoid a NullReferenceException
. This article explains how to use these operators.
Consider this code. It throws a NullReferenceException
.
1internal class Program
2{
3 private static void Main(string[] args)
4 {
5 Item item = null;
6 Console.WriteLine($"Name: {item.Name}");
7 }
8}
9
10internal class Item
11{
12 public string Name { get; }
13}
To fix this code, we could add an if
statement to check for null.
1private static void Main(string[] args)
2{
3 Item item = null;
4
5 if (item != null)
6 {
7 Console.WriteLine($"Name: {item.Name}");
8 }
9 else
10 {
11 Console.WriteLine($"Name: ");
12 }
13}
However, the above code increases the complexity and creates another code path.
Another way to solve this issue is to use a null-conditional operator, ?
.
1private static void Main(string[] args)
2{
3 Item item = null;
4 Console.WriteLine($"Name: {item?.Name}");
5}
The part to the right of the ?
only evaluates if the part to the left is not null. Otherwise, the code returns null. So, in the case above, item?.Name
evaluates to null, but it does not throw an exception because there is no attempt to access a member on a null reference. Use the null-conditional operator on members of namespaces, types, array elements, access methods, or to invoke delegates.
The class below has two methods that raise an event. The dangerous version throws a NullReferenceException
if there is no event handler attached. The safe version does not. It is always safe to call the method, even when there is no event handler attached.
1public class LongProcess
2{
3 public event EventHandler<string> Finished;
4
5 public void FinishSafely()
6 {
7 Finished?.Invoke(this, "The process finished successfully");
8 }
9
10 public void FinishDangerously()
11 {
12 Finished.Invoke(this, "The process finished successfully");
13 }
14}
??
is the null-coalescing operator. It returns the value of the part on the left if it is not a null reference. Otherwise, it returns the value of the part on the right. Use this operator to fall back on a given value.
In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned. This code returns the name of an item
or the default name if the item
is null. As you can see, this operator is a handy tool when working with the null-conditional operator.
1private static void Main(string[] args)
2{
3 var defaultName = "Default";
4 Item item = null;
5 Console.WriteLine($"Name: {item?.Name ?? defaultName}");
6 Console.ReadLine();
7}
Output:
Default
From C# 7 onwards, it has been possible to use the null-coalescing operator to shorten the validation of arguments. This class requires the message
argument in the constructor. Before C# 7, validation would require an if
statement.
1internal class MessageProcessor
2{
3 private readonly string _Message;
4
5 public MessageProcessor(string message)
6 {
7 if (message == null) throw new ArgumentNullException(nameof(message));
8 _Message = message;
9 }
10}
Using the null coalescing operator allows this to be shortened to the code below.
1internal class MessageProcessor
2{
3 private readonly string _Message;
4
5 public MessageProcessor(string message)
6 {
7 _Message = message ?? throw new ArgumentNullException(nameof(message));
8 }
9}
Null checking is important for code stability. The null-conditional operator can be used to simplify null checking. The null-coalescing operator is a great complement to it and can further simplify code where the aim is to return something other than null.