Dotnet logo

.NET Tools

Essential productivity kit for .NET and game developers

.NET Tools ReSharper Platform Rider

Taming the Billion Dollar Mistake: Maarten Balliauw’s Guide to C# Nullable Reference Types

At the most recent JetBrains.NET Days Online 2025 event, Maarten Balliauw delivered a comprehensive session on migrating existing codebases to use C# nullable reference types, a feature that’s been available since C# 8 but remains underutilized in many legacy projects. Through practical examples and migration strategies, Maarten demonstrated how to bring null safety to your existing code without drowning in thousands of warnings.

Watch the full presentation

#nullable enable – Unlock the Power of C# Nullability — Maarten Balliauw

It’s not for runtime safety

Maarten opens with a crucial clarification that sets realistic expectations for the entire migration journey: “There is no runtime safety for nullable reference types. It is design time and compile time that help to check whether something can be null or not.” This isn’t a silver bullet that will eliminate all null reference exceptions – it’s a tool to help developers make better decisions while writing code.

The feature essentially flips the traditional C# paradigm. As Maarten explains, “The idea is that when you’re writing code, every single type that you have is going to be non-nullable by default. And there is a syntax to annotate a reference type as being nullable.” This inversion makes nullability explicit rather than implicit, forcing developers to think intentionally about null handling.

The Boy Scout Rule for migration

When it comes to migrating existing codebases, Maarten advocates for a pragmatic approach. For smaller projects, you might enable nullability project-wide and plow through the warnings. But for larger codebases, he recommends the Boy Scout Rule:

“Keep it disabled at the project level. And whenever you touch a piece of code, you enable it file by file and just work your way through until the entire project is converted.”

The key insight for where to begin? “Start at the center and work outwards” (29:59). Maarten suggests starting with classes that have few dependencies but are used extensively throughout the codebase, typically data transfer objects and domain models. A small change in these central classes can eliminate warnings across your entire codebase.

The temptation of the dammit operator

Throughout the presentation, Maarten repeatedly warns against one particular anti-pattern: the null-forgiving operator (!), also known as the “dammit operator”. His stance is unequivocal: “The null forgiving operator is an anti-pattern.”

Why such strong language? “You’re lying to the compiler. You’re lying to yourself when you are working in this codebase a couple of months after you first wrote the code.” While the operator can be useful during migration to temporarily suppress warnings, Maarten emphasizes that production code should never ship with these suppressions.

Embracing null, not fighting it

In a refreshing perspective shift, Maarten reminds developers: “Don’t be afraid of null. Nullable reference types will help you get more confidence in compiler and IDE flow analysis. It’s impossible to get rid of all of the null usages in code” (37:23). The goal isn’t to eliminate null entirely, it’s to build a safety net for dealing with it effectively.

This philosophy extends to library authors, who need to consider consumers using different languages. Since nullable reference types are C# only, libraries should still include runtime null checks for robustness, especially when the API might be consumed by F# or VB.NET code that won’t benefit from the nullable annotations.

Entity Framework’s surprise

One of the most valuable warnings in the presentation concerns Entity Framework Core, which has a potentially breaking behavior: “The Entity Framework Core team, unfortunately, did look at this, and they are actually updating your database schema based on nullable reference types.”

This means that enabling nullable reference types can inadvertently trigger database schema changes, something that might slip past developers but certainly won’t escape the notice of your DBA. It’s a “gotcha” that Maarten admits makes sense from Entity Framework’s perspective, but one that can be an unwelcome surprise during migration.

Practical tools for the journey

Maarten highlights several tools that make migration more manageable (38:28). The value tracking feature in Microsoft Visual Studio and Rider helps trace where properties are set, making it easier to determine if something can actually be null. The automatic migration tools can get you quite far along the way by running flow analysis and making educated guesses about nullability.

For JSON serialization scenarios, Maarten presents multiple strategies, with his personal favorite being the use of the required keyword combined with proper validation, rather than littering code with null-forgiving operators or losing type safety by making everything nullable.

The takeaway

Maarten’s session demystifies the migration to nullable reference types, presenting it not as an all-or-nothing proposition but as a gradual improvement process. His closing summary captures the essence perfectly: “Nullable reference types give you design time and compile time safety in .NET, not at runtime.”

This session serves as both a technical guide and a philosophical framework for approaching nullability. It’s not about achieving perfection or eliminating all nulls – it’s about making your codebase more predictable, maintainable, and explicit about its null-handling intentions.

For teams sitting on legacy codebases wondering if the migration effort is worth it, the essence of Maarten’s argument is that the investment in nullable reference types pays dividends in code clarity, reduced bugs, and better communication of intent between team members, including your future self.


Follow Maarten Balliauw’s work on nullable reference types and other C# topics on his blog, X, and Bluesky.

Watch the full recording of this year’s online event on YouTube:

▶️ Day 1: Aspire, Clean Architecture, C# Nullability, Messaging, Uno, Blazor TDD.

▶️ Day 2: Event-Driven Systems & GenAI Qith Aspire, F#, dotMemory, and More.

You may also find these interesting:

The Null-Forgiving Operator in C# Is a Code Smell(!)  by Matthew Champion.

Nullable reference types in C# – Migrating to nullable reference types by Maarten Balliauw. 

Nullable reference types and nullability in EF Core by Damir Arh.

Null & Void – Everything About Nothing in .NET – a presentation given by Stefan Pölz at .NET Days Online 2021. 

image description