C# 8.0 Nullable References

February 18, 2019 |

The What and Why of ‘nullable references’

If you ask a developer what kind of exception he most often sees when developing a application its almost certainly the NullReferenceException. Even the best developers will forget a null check sometimes.

It all began in 1965 when Tony Hoare invented the NullReference, basically a reference that does not reference a valid object. This has let to numerous errors, vulnerabilities and system crashes. The inventor of the null reference even calls it The Billion Dollar Mistake.

In my opinion I don’t see null references themselves as a bad thing. They can be a very useful representation of nothing, empty etc. Problems start however when everything in a programming language is nullable by default. In fact in C# you don’t even get to choose this for reference types. In alot of cases nullability is not actually needed and only opens the door to the dreaded NullReferenceException we all see too often.

So what the new nullable reference feature in C# 8.0 does is making everything non nullable by default. If you want a reference type to be possibly null you now have to be explicit about it by adding a ? at the end of the type name.

How does this help with null references?

Now the type system itself has information about whether something can be null or not it can warn the developer if rules are broken. It also more clearly communicates the intent to your fellow developers. No more guessing or diving in the documentation to see if a return value can be null!

In Visual studio 2019 with nullable references enabled (for more info on how to do this yourself see the bottom of this article) we take a look at the following method that has a non nullable parameter:

public static void MethodWithNonNullableParameter(SomeClass someclass)
{
}

The above method needs a parameter of type SomeClass and it cannot be null. The compiler will warn you if you put in a possible null:

SomeClass? value = null;
MethodWithNonNullableParameter(value); //Gives a warning because we are passing a possible null to a non nullable parameter

Adding a null check will solve the warning:

SomeClass? value = null;

if(value != null)
{
    MethodWithNonNullableParameter(value); //No warning here because of the null check
}

You are not limited to method parameters or local variables. A property or field can be made nullable too:

public class SomeClass
{
    public SomeClass? SomeProperty { get; set; }
    public SomeClass? SomeField;
}

Shortcomings

Its important to note that the nullable references feature will not spot all possible null reference exceptions. There are cases where, atleast in the VS2019 preview 4, it will fail to spot a null reference exception such as this one:

var array = new SomeClass[100];
MethodWithNonNullableParameter(array[0]); //No warning even though this will produce a null reference exception

In the current state nullable references does not understand the TryGetValue pattern:

var dic = new Dictionary<int, SomeClass>();
dic.TryGetValue(3, out var someClass);
MethodWithNonNullableParameter(someClass); //No warning even though this will produce a null reference exception because we forgot checking the returned bool of TryGetValue

Testing it out yourself

To test out nullable references yourself you have 2 options

  • Install the preview of Visual Studio 2019
  • Test out nullable references in Sharplab

Regardless of which option you take you will notice nullable references are not enabled by default. You have enable the feature by adding #nullable enable to the code:

class Program
{
    #nullable enable
    static void Main(string[] args)
    {
    }
}

If you are using .NETcore it will also be possible to enable nullable references by adding <NullableContextOptions>enable</NullableContextOptions> to the .csproj file. I could not get this to work for .NET framework projects in the current VS2019 preview 4.