Why You Should Care About C#’s ‘Nullable Reference Types’

04-Sep-2025

and How They Help Prevent Null-Related Errors

Why You Should Care About C#’s ‘Nullable Reference Types’

If you have ever worked with C#, you are likely aware on some level of the dreaded NullReferenceException. The NullReferenceException is one of the most feared runtime errors of any application, and its undesired effect of crashing programs while simultaneously wasting developers’ time during debugging sessions is notorious. The exception is thrown at runtime when an attempt is made to use a member (e.g., property, method, etc.) or access a member variable on an object if the object that the member uses is null.

Fortunately, with the introduction of C# 8.0, you can avoid these dreaded null-related issues by taking advantage of the new feature, Nullable Reference Types, to enforce stricter null-safety rules in your code. Nullable Reference Types help ensure that you investigate your null references at compile-time, giving you an early warning system against potential null reference bugs instead of affecting them at runtime. In this article, we will look at what nullable reference types are, how they enhance safety in your code, and how you can leverage them to write better and more reliable C# code.

What Are Nullable Reference Types?

For reference types in C#, such as string, class, and object, assigning a null value is the default behavior. As a developer, you may appreciate your flexibility, but the concern is being affected by null-related errors if you did not perform a check for a reference type prior to utilizing it.

Before C# 8.0, C# had no way to distinguish between reference types that may or may not be initialized as null. As such, initializing objects and checking them for null before using them was left purely to the developer. C# 8.0 introduced Nullable Reference Types, which is a new way to state if a reference type is null. This is done using the? symbol to specifically designate a type to be null.

  • Non-nullable Reference types: All reference types are non-nullable by default. This means you may not assign null, unless you explicitly declared it as a nullable reference type.
  • Nullable Reference types: You may declare a reference type as nullable just by stating a ? after the type declaration, meaning that it may contain null.

Let’s consider an example:

#nullable enable // Enable nullable reference types
public class Person
{
public string Name { get; set; } // Non-nullable
public string? Nickname { get; set; } // Nullable
}
var person = new Person();
person.Name = "John";
person.Nickname = null; // This is valid because Nickname is nullable.

Name is a non-nullable reference type (it cannot be null), while Nickname is a nullable reference type (string?), meaning it can be set to null.

How Nullable Reference Types Offer Better Safety

The biggest advantage of nullable reference types is that they add compile-time safety checks to avoid NullReferenceException errors. If you turn on nullable reference types, the compiler will warn you if you try to assign null to a non-nullable reference type or if you try to dereference a nullable reference type without checking if it is null.

1. Compile-Time Null Safety

When you have nullable reference types on, the compiler checks to make sure you handle potential nulls correctly. As an example, if you try to assign null to a non-nullable reference type, you will get an error:

#nullable enable
public class Person
{
public string Name { get; set; } // Non-nullable
}
var person = new Person();
person.Name = null; // Error: Cannot assign null to non-nullable reference type.

This lets you catch a potential bug before you even run your code, which should let you make your programs less surprising and more stable.

2. Preventing Unintentional Null Dereferencing

Another benefit is avoiding accidentally dereferencing null. When you try to reference a nullable reference type without checking to see if it is null, the compiler will warn you:

#nullable enable
public class Person
{
public string? Name { get; set; }
}
var person = new Person();
Console.WriteLine(person.Name.Length); // Warning: Dereferencing a nullable value.

Name is nullable (string?) here, and getting its Length property without any null check would throw a runtime exception. The compiler warns you of this possibility before you even run the code.

3. Better Code Readability and Clarity of Intent

Using nullable reference types makes your code more expressive and easier to read. You can instantly see for which properties or variables it is possible that they hold a null value for which makes it easier to think about the code and not include unnecessary null checks.

public class Person
{
public string Name { get; set; } // Non-nullable reference type
public string? Nickname { get; set; } // Nullable reference type
}

In the above case, it is easy to see that Name will never be null, but Nickname can be null. As a result, you can have an easier time avoiding some bugs when working with those properties.

Migrating an Existing Project to Nullable Reference Types

Migrating an existing project to nullable reference types is a simple process; however, it could require some refactoring to handle existing non-nullable code with respect to the new nullability rules.

Steps to take:

1. Allow Nullable Reference Types

First, you will want to allow nullable reference types. You can allow them globally in your (.csproj) project file or on a per-file basis with the#nullable enable directive.

  • Global Allowance: If you want to allow nullable reference types as a project, then add this to the .csproj file:
  • <Nullable>enable</Nullable>
  • Per-File Allowance: If you want to globally allow nullable reference types, but only for certain files, then add the following directive at the top of your C# Files
  • #nullable enable

2. Resolving Warnings and Errors

Once nullable reference types have been enabled, you will probably have warnings in places where you are not handling nullability as intended. For example, assigning null to a non-nullable reference type or dereferencing a nullable type without a null check will both show warnings.

You can handle these warnings in a few different ways:

  • Mark types as nullable: Use the ? to mark types that can be null.
  • Check for null: Use a null check or a null-conditional operator to be sure that the nullable reference types are only accessed if they are not null.
public string? GetName(Person person)
{
return person?.Name; // Safe access with null-conditional operator
}

3. Staged Migration

You don’t have to change everything all at once. You can begin by enabling nullable reference types in areas where nulls might cause serious issues, and then incrementally refactor the rest of your codebase. This allows you to deploy a feature that is iterative while also safeguarding your application.

4. Suppressing Warnings

If you have some cases where you know a nullable reference type will never be null, you can use the! operator, the null-forgiving operator, to suppress the warnings.

string name = person.Name!;  // Suppress warning assuming Name will never be null.

But use this carefully because it can lead to run-time errors when the assumption is wrong.

Code Examples: Demonstrating Nullable Types in Practice

Now let’s look at some example code and see how nullable reference types work practically.

Example 1: Nullable Reference Types in Practice

#nullable enable
public class Person
{
public string? Name { get; set; }
}
var person = new Person();
person.Name = null;
if (person.Name != null)
{
Console.WriteLine(person.Name.Length); // Safe to access Name, as null is checked first.
}
else
{
Console.WriteLine("Name is null");
}

In this example:

  • Name is nullable (string?), so it is valid to assign null to it.
  • We check to see whether Nameis null before we access the Length property, so that we do not throw an exception at run-time.

Example 2: Non-nullable reference types

#nullable enable
public class Person
{
public string Name { get; set; } // Non-nullable
}
var person = new Person();
person.Name = null; // Error: Cannot assign null to a non-nullable reference type.

Here, It Name is a non-nullable reference type, so you cannot assign null to it, and the compiler will provide an error at compile time, preventing a possible null.

Best Practices to Avoid Null Issues in C#

While nullable reference types greatly mitigate null issues, there are a few best practices to adhere to to avoid null issues:

  1. Mark Nullable Types Explicitly: Avoid overuse of nullable reference types. Only mark a reference type as nullable when it has real significance in your model (i.e., an optional property or parameter).
  2. Use Null-Conditional Operators: Utilize the null-conditional operator (?.) to safely access nullable reference types; this way, you won’t have to worry about triggering a NullReferenceException.
string? name = person?.Name;  // Returns null if person is null

3. Check for null Before Usage: When using nullable reference types, always check for null before using them. This will help prevent you from accidentally dereferencing a null reference.

4. Use IDisposableto Manage Unmanaged Resources. While nullable reference types are helpful,

5. Use the Null-Forgiving Operator (!Only When Necessary
If you are completely certain that the nullable reference will not be nullYou can suppress the compiler warning with the null-forgiving operator (!)

string name = person.Name!;

6. However, this circumvents the compiler’s safety functionality and should only be used when necessary. It is like saying to the compiler, “Trust me, I know what I am doing.” You still risk throwing a runtime exception if you are wrong.

7. Prefer Constructor Initialization for Required Properties
When working with non-nullable properties, initialize them through constructors to ensure they’re always set when an object is created:

public class Person {
public string Name {
get;
}

public Person(string name) {
Name = name;
}
}

8. This method enforces immutability and guarantees the required values to always available.

9. Use Annotations and Contracts for Better Clarity
When authoring APIs or libraries, adding attributes such as [NotNull], [MaybeNull], or XML documentation can make your intent clearer and enhance tool support.

Summary: Why Nullable Reference Types Are Worth the Effort

Nullable reference types in C# represent more than a language feature — they are a change in philosophy towards safer, more defensive, and more intentional programming. If you enable this feature, you will:

  • Catch issues related to null before they can crash your app.
  • Be better understood by other developers (and your future self).
  • Create code that is easier to maintain and reason about.
  • Reduce runtime exceptions and improve app stability.

Simply put, nullable reference types are a way to get the compiler to do more of the heavy lifting for you, to allow you to write applications that, before this point, are robust and resilient

Are You Ready to Enable It?

If you are building new applications or maintaining high-value production applications, enabling nullable reference types is one of the easiest and most powerful mechanisms for quick-better-code-now!

To recap:

  1. Enable it in your .csproj file:
<Nullable>enable</Nullable>
  1. Start annotating your code with ‘?’ where null is an acceptable option.
  2. Fix all the compiler warnings, and be aware of the null-checking best practice.
  3. Expect fewer bugs and more confidence that your code is right.

Final Thought

In today’s .NET world — with C# powering everything from web applications to cloud computing and cross-platform mobile apps — null-safe code is more than a best practice: it’s required.

Nullable reference types add compile-time safety to one of the most dangerous areas of programming. It might feel like a small step forward, but the impact this can have on the quality of your code cannot be understated. So next time you have a ? in your type declaration, consider it not a pain in the butt, but rather as a guardian-keeping your code safe from the sneaky bugs that go undetected… until your app goes down on production time.


Why You Should Care About C#’s ‘Nullable Reference Types’ was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.

Also read: Tesla promet de révolutionner le monde et l’humanité avec son nouveau plan
WHAT'S YOUR OPINION?
Related News