C# 8 lets a reference type declare whether it may be null, which turns the language’s oldest category of bug into a compile-time warning — on an existing codebase, thousands of them.
#nullable enable
public class Order
{
public string Reference { get; set; } = string.Empty; // never null
public string? Note { get; set; } // may be null
}
// and the migration lever: per file, not per project
// <Nullable>enable</Nullable> in the csproj turns it on everywhere
The per-file #nullable enable is what makes this adoptable — the same shape as a PHPStan baseline, applied one file at a time rather than as a four-thousand-warning wall. The null-forgiving ! operator is the escape hatch and every use of it is a claim the compiler cannot check, so it is worth grepping for periodically. This is the same problem PHP has with strict_types and typed properties, solved with the same incremental strategy.