The Null Conditional Operator is used for easier checking of null values for every member in object property path. We use the ?operator after a member or a method call then followed by another nested member. Here is the syntax:

Member?.Member2?....MemberN;

Before the null conditional operator, when we have the following expression with a very long call chain, we get the risk of any of the members in the chain being null and causing NullReferenceException.

int? value = myObject.Member1.AnotherMember.LastMember.IntProperty;

So what we do is write a series of null checks like this for every member in the object path.

int? value = myObject != null &&
    myObject.Member1 != null &&
    myObject.Member1.AnotherMember != null &&
    myObject.Member1.AnotherMember.LastMember != null ? myObject.Member1.AnotherMember.LastMember.IntProperty : null;

With the introduction of the null conditional operator in C# 6, this can now be significantly simplified into this one line of code.

int? value = myObject?.Member1?.AnotherMember.?LastMember?.IntProperty;

The way the null conditional operator works is that it checks if the first object in the path is null. If it is not, then we proceed to the member it is addressing next, otherwise, we immediately return null as the result of the expression. If the first object is not null, we proceed to the next member in the path that it is calling. If that next member is null, then again, we stop and return null as the result of the expression. If it is not null, then we proceed again to the next member until we reach the last member in the path. In our example, if any of the members before IntProperty is null, then it will immediately assign null as the value for the variable. Of course, we have to use a nullable type as the type of the variable as the expression could return null if any of the members in the path are null.

The null conditional operator can be used on any type of member, whether it be property, method, or an element of a collection.

Here’s an example where we check if the object is null first before invoking one of its method.

int? highestGrade = student?.GetMaxGrade();

If the student is not null, then that’s when we invoke the method, otherwise, the variable highest grade will have null value.

Here’s another example where we apply it to the return value of a method. Since we are not sure whether a method will return a non-null value before calling the members of its return type, we used the null conditional operator.

int? age = person.GetPersonalInformation()?.Age;

We can check if a certain array, collection, or dictionary is null before invoking their indexer.

double? grade = person.Subjects?[0].Grade;

The null conditional operator is a perfect complement to the null coalescing operator (??). We can assign a default value if the expression with the null conditional operator returns null.

int age = person?.Age ?? 0;

If the person is null, then the default value of 0 will be assigned to the age variable.

One limitation of the null conditional operator is that you cannot use it directly when invoking delegates or events.

public class Program
{
    public delegate int MyDelegate(int x);

    public static void Main(string[] args)
    {
        MyDelegate myDelegate = null;

        int? result = myDelegate?(5); // ERROR
    }
}

Instead, you need to use the Invoke method.

int? result = myDelegate?.Invoke(5);