The null propagation operator - NULLET (C# 6)

C# 6

Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

NULLs—you either hate them or loathe them. They are the source of so many issues in the apps we write, especially the dreaded NullReferenceException. The current fix is to be very defensive in your programming, for example:

public static void Exception(Track track)
{
    // this may cause an exception if the track object, band property or the frontman property is null
    Console.WriteLine("HI! " + track.Band.FrontMan.Name);

    // defensive programming to avoid null exceptions
    if (track != null && track.Band != null && track.Band.FrontMan != null)
    {
        Console.WriteLine("HI! " + track.Band.FrontMan.Name);
    }
}

Constant null-checking also makes working with events particularly ugly, because you need to check for nulls before you call an event:

internal class NullConditionalEvent : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePain(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

NULLET

Clipboard01 With C# 6, a new operator has been added: the null propagation operator (?). Some people have taken to calling it the Elvis operator (since it resembles two eyes and a splash of hair), though I think the hair resembles more of a mullet—so I’ve adopted the term "NULLET operator".

The nullet operator allows you to check for nulls, so we can rewrite the first example as follows—which will not raise a null exception:

public static void Exception(Track track)
{
    Console.WriteLine("HI! " + track?.Band?.FrontMan?.Name);
}

Here’s how the nullet works: it tells .NET to check if the preceding item is null before moving to the next. If an item is null, evaluation stops there, returning null. For example, with track:

image

For deeper insights, check out this post on the Roslyn Codeplex site.

The key question: What happens if any of the properties are null? The result becomes "HI! " (since "HI!" + NULL truncates to just "HI!").


Events & Methods

The first example showed how null checks clutter event handling. With nullet, we can simplify this—for events (and any delegate):

private void RaisePain(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

To call the event, we need a fallback action (like Invoke). This also proves nullet isn’t just for properties—it works with methods too.


Null + Indexers = Support for Arrays & Lists

Nullet also supports indexers, with a slight syntax tweak: replace ?. with just ?.

Track[] album1 = null;
Console.WriteLine("Album 1 Track 6 " + album1?[5]);

List<Track> album2 = null;
Console.WriteLine("Album 2 Track 3 " + album2?[4]);

Both examples execute without null issues because the ? prevents cascading exceptions.


Not the End of Null Pain

Nullet is a shortcut that prevents NullReferenceException, but null-related exceptions can still occur. For example, Enum.Parse throws a NullArgumentException if given null:

Enum.Parse(typeof(Example), track?.Band?.FrontMan?.PrimaryInstrument);

Fix: Check for nulls manually where needed, but use nullet for cleaner code:

if (!string.IsNullOrWhiteSpace(track?.Band?.FrontMan?.PrimaryInstrument))
{
    Enum.Parse(typeof(Example), track?.Band?.FrontMan?.PrimaryInstrument);
}