Saturday, August 15, 2015

C# Null-Conditional Operator

With the recent release of Visual Studio 2015 we also get the new version of C# with some nice new language features. In this post I will talk about one of my favorites, the Null-Condition Operator.
Let’s say I have these two classes (obviously over simplified for the purposes of this article)…

class SalesOrder
{
    public Address SoldTo;
}

class Address
{
    public string PostalCode;
}


If  we then declared an instance of SalesOrder and wanted to access the PostalCode property and trim off the spaces we would do this…

string zip = order.SoldTo.PostalCode.Trim();

This line would work ok only if order, SoldTo and PostalCode were not null, if any of them were you would get a Null Reference Exception. To handle this in the past we would have to create an if statement to check each part to see if it’s null before we try to trim the postal code.

In C# 6.0 we can solve this problem using the Null Reference Operator which makes for much cleaner code.

string zip = order?.SoldTo?.PostalCode?.Trim();

The question mark after each part is the null reference operator. When the code is being executed, if the part before the question mark is null execution of the line will end and null will be returned. So if order, SoldTo or PostalCode is null, zip will be set to null without an exception being thrown. If order and SoldTo both had values and PostalCode was null the null reference operator after PostalCode will prevent Trim from throwing and exception. As soon as the program sees that PostalCode is null it will skip the attempt to execute Trim().

You can also use this on arrays and collections like this…

List<SalesOrder> orders = null; 
order = orders?[1];

If the null reference operator was not used in the second line, this would throw a null reference exception because orders is null. With the operator the order variable will be set to null.

When new features like this are added to the language I always like to take a look at a disassembly of the code to see how the features are implemented. Nothing too surprising here, it’s done pretty much how we would have done it before this feature was added. Note that each part of the assignment is assigned to a variable before the null check is done. This is done in case there is a function call so it doesn’t get called more then once.

    if (salesOrder != null)
    {
        Address soldTo = salesOrder.SoldTo;
        if (soldTo != null)
        {
            string postalCode = soldTo.PostalCode;
            if (postalCode != null)
            {
                str = postalCode.Trim();
            }
            else
            {
                str = null;
            }
        }
        else
        {
            str = null;
        }
    }
    else
    {
        str = null;
    }