Nullable Types in C#
How C#'s nullable reference types and nullable value types help catch null-reference bugs before runtime.
2 min read
NullReferenceException is infamous enough in C# circles to have its own nickname: "the billion-dollar mistake," after Tony Hoare's own description of inventing null references. Modern C# gives you real tools to catch these before they crash a program in production.
Value types aren't nullable by default
int age = null; // compile error: int can't be nullValue types like int, bool, and double always hold a real value — there's no "empty" int. To allow null, add ?:
int? age = null; // nullable int
bool? isActive = null; // nullable boolint? is shorthand for Nullable<int>, a small wrapper type with .HasValue and .Value properties:
int? age = null;
if (age.HasValue)
{
Console.WriteLine(age.Value);
}
else
{
Console.WriteLine("No age set");
}Nullable reference types
Reference types (string, classes) could always be null historically — that was the whole problem. Since C# 8, projects can opt into nullable reference types, which flips the default: a plain string is now assumed non-null, and you must explicitly write string? to allow null.
#nullable enable
string name = "Ada"; // compiler assumes this is never null
string? nickname = null; // explicitly allowed to be null
Console.WriteLine(name.Length); // fine
Console.WriteLine(nickname.Length); // compiler warning: nickname might be nullThis is enabled by default in new projects (<Nullable>enable</Nullable> in the .csproj, which the setup lesson mentioned). It doesn't stop null at runtime by itself — it's a compile-time warning system that flags places where you're about to dereference something that might not exist.
Safely working with nullable values
The null-conditional operator (?.) short-circuits to null instead of throwing:
string? name = null;
int? length = name?.Length; // null, not an exceptionThe null-coalescing operator (??) supplies a fallback:
string displayName = nickname ?? "Anonymous";And ??= assigns only if the variable is currently null:
nickname ??= "Anonymous";Combine ?. and ?? and you get a compact, safe way to unwrap something that might not be there:
int nameLength = name?.Length ?? 0;Treat nullable warnings as bugs to fix, not noise to suppress — they're the compiler doing exactly the job it's meant to do.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.