C# 8 Nullable Reference Types

C# 8.0 will introduce a new groundbreaking feature called Nullable reference types, this feature will change the way we currently develop our software in C# by making, you guessed it, reference types nullable.

This post serves as a practical introduction to the problem and how you should solve those problems.

Why should we use it?

There are multiple benefits in using this feature. The first and foremost is type safety for reference types. In the end it is very weird that we can assign a value to a reference type that is not of that type. For example:

string helloNull = null; 

Will cause a compiler butt kick, because null is not a string!

The second benefit is that it will make the intent of your code very clear. It tells you and the users of your solution how your code should be used and handled. In the blink of an eye you’ll see what this code should do, and if your are doing it wrong the compiler tell you.

The whole ecosystem including all the libraries that we all use will eventually be safer to use because they generate no null reference error and the intent of the libraries is also much more clear!

If you are still not convinved that null is a bad idea, then the creator of the billion dollar mistake also know as null has publicly apolizeged for introducing it.

Enabling

As this is a breaking change we need to enable it. Add the following to your csproj or maybe even better to your Directory.build.props:

<LangVersion>8</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NullableReferenceTypes>true</NullableReferenceTypes>

Also make sure your that all your projects target .NET Core 3.0 or higher.

Welcome to .NET Hardcore

.NET Hardcore

Errors

When .NET Hardcore mode is on we will find lots of errors in our current codebase. We are only fixing the nullable references type which should be explicit. In the end it means when we fix these errors we will get to the real bugs, that only you can fix.

Nullable parameters

When we give a method a nullable parameter often we mean that this parameter is optional.

The error we would now run into is:

CS8625 Cannot convert null literal to non-nullable reference or unconstrained type parameter.

To fix this can make Username nullable by adding the ?. Note that we also have to do this for the property.

Non-nullable properties that are uninitialized

When we create properties we often don’t think about the consequences and if they should be nullable or not. For example we could have:

Which is fine in the old world but it will now generate an error that you are almost definitely our going to encounter:

CS8618 Non-nullable property ‘PropertyName’ is uninitialized.
CS8618 Non-nullable field ‘FieldName’ is uninitialized.

To fix these we should decide if this property should be nullable or not. If its nullable we append the ? to it:

If it should not be nullable we need to set it! So either give a parameter that initiliazes it or set a default value:

Returning null

Sometimes we tend to return null because we didn’t do anything with the results:

The error we encounter is:

CS8603 Possible null reference return.

You could argue that this might be a code smell but to fix it we should always return a initiliazed list or we should change the signature to make it return null:

Another interresting case for this error might be that you are checking for null values, and if they are null, you are returning null as well:

To fix it, either decide to make your parameter nullable or to make it explicit:

Possible dereference of a null reference

This is the hardest one i found so far, and i didn’t fully understand it yet. An example of where i encountered this error is:

CS8602 Possible dereference of a null reference.

Note that the list is nullable, so to fix this we should check if the list is != null. What is really going on is that the compiler is warning us that the reference value may be mutated to null.

Conclusion

While doing this work a lot of your codebase while change and errors will bubble up to the real problem you got to fix. This mostly means deciding if something should be null or not. When that is done your codebase quality is improved and the intent will be much clearer.

Nullable reference types seem like a great way forward and i can’t wait till everbody is using this feature to make our ecosystem so much better.