How Do C#'s Nullable Reference Types Work?

C # logo

One of the main features of C # 8.0 is the concept of nullable reference types, which represent a major change in the way programmers can handle null data. We will discuss how they work and how to use them.

What are the nullable reference types?

There are two main types of variables in C #. Value types have fixed sizes, like int, float, and bool. They are passed between functions by value and usually stored on the stack – a very fast memory that is cleaned up if the range is exceeded. They can never be zero, but using the Nullable struct, value types can be designed to support null data if you want this behavior.

RELATED: How does memory management work in C #?

The other type of type is reference types, which are larger objects with no fixed size, such as strings and lists. They are almost always stored on the heap, with the variable on the stack being a reference to the memory location.

The problem is that the reference types can become null. The variable that stores the location can be set to a null value, which is quite common, especially when it comes to data that is not guaranteed to be present, like optional questions in a web form. That’s why .NET needs a garbage collector, to clean up objects that no longer have active references.

If you are a .NET programmer, you are definitely used to zero verification, in which you manually check if something has become null before using it. It works well, and it is a very cheap operation, but in many cases it is not necessary. For a reference type to be null, it must either not have been initialized with an appropriate value or have been manually assigned to the value of null, for example.,

variable = null;

Nullable reference types are a new addition that essentially applies a difference between reference variables that can become null and reference variables that cannot. It’s a revolutionary feature that will likely leave your codebase with a lot of warnings, so it’s something you need to manually activate. Once activated, the compiler starts to differentiate between:

  • string?, which can be null and retains the “default” behavior of earlier versions, and
  • string, which can not be zero. It can never be null, because it must be assigned a default value and can never be set to null.

With the feature enabled, reference types will work in much the same way as value types – never becoming null unless you tell the compiler it can with the Type? syntax. Technically, “nullable reference types” are what C # has had forever, and the new feature is non-nullable reference types replacing the old ones.

This simple functionality allows you to inform the compiler of your intentions for the variable. If you try to assign a nullable string? value to a non-nullable string variable, you will receive a warning that you are not handling null correctly.

Should you assign a nullable string? value to a non-nullable string variable, a warning is given because you are not handling NULL correctly.

To correct this warning, you must set the non-nullable value only after checking if it is not null. The compiler is smart and knows when and where the value can be zero. If you wrap it in a if (value != null) blocked, it will not give you a warning and remind you that it is not null when using it.

If you wrap it in an if block (value! = Null), it will remind you that it is not null when used.

Unlike nullable value types, nullable reference types are implicitly converted to their non-nullable equivalents, but with a warning.

You can use nullable reference types anywhere you can use regular types, be it as a local variable, fields or properties for classes and structures, and input parameters for functions. If you try to convert them to non-null without checking, you will get an error.

If you convert non-nullable to non-null reference types without checking, you will get an error.

How to activate null context

In Solution Explorer, right click on your project and select “Edit Project File”. You may need to unload it first to see this option.


If you are using the legacy project format, you may need to manually override it with a directive at the top of each file:

#nullable enable

If you do not want to activate the warnings, you can use the “Annotation” context, which will only display annotations when you hover over them.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.