Nullable Reference Types
C# / .NET Interview Notes
1. Big Picture
Before C# 8.0, reference types were implicitly nullable — any string could be null, and the compiler said nothing. This caused billions of NullReferenceExceptions. Nullable Reference Types (NRT) make nullability explicit at compile time.
string → "I will never be null" (compiler enforces)string? → "I might be null" (you must check)string! → "Trust me, not null" (suppress warning)2. Enabling NRT
In .csproj:
<PropertyGroup>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
Or per-file: #nullable enable
3. Nullable vs Non-Nullable
string name = "Alice"; // non-nullable — compiler guarantees not null
string? nickname = null; // nullable — must check before use
// nickname.ToUpper(); // WARNING: may be null
if (nickname != null)
{
Console.WriteLine(nickname.ToUpper()); // safe
}
4. Null-Forgiving Operator (!)
Suppress the warning when you know better than the compiler:
string? input = GetInput();
string result = input!; // "trust me, it's not null"
// Dangerous if you're wrong — NullReferenceException at runtime
! suppresses the compiler warning but provides no runtime safety. Use sparingly.
5. Null-Coalescing Operators
?? — provide a default if null:
string? name = null;
string display = name ?? "Anonymous"; // "Anonymous"
// ??= — assign if null
name ??= "Default";
// ?. — null-conditional
int? length = name?.Length; // null if name is null
6. Flow Analysis
The compiler tracks null state through your code:
void Process(string? input)
{
if (input == null) return;
// Here, compiler knows input is NOT null
Console.WriteLine(input.Length); // no warning
input = null;
// Now compiler warns again
// Console.WriteLine(input.Length); // WARNING
}
7. Nullable Value Types
Value types can also be nullable with ?:
int? age = null; // nullable int
bool? isActive = null; // nullable bool
int actual = age ?? 0; // unwrap with default
if (age.HasValue) { Console.WriteLine(age.Value); }
8. Common Patterns
Guard Clause
void Save(User? user)
{
if (user is null) throw new ArgumentNullException(nameof(user));
// user is now non-null for the rest of the method
_db.Save(user);
}
Early Return
string FormatName(Person? person)
{
if (person is null) return "Unknown";
return $"{person.FirstName} {person.LastName}";
}
Pattern Matching with Null
if (input is not null && input.Length > 0)
{
// safe to use input
}
9. Common Interview Questions
Q: What is the difference between string and string??
With NRT enabled, string is non-nullable (compiler enforces), string? is nullable (must check). Without NRT, both behave the same at runtime.
Q: Does NRT add runtime overhead?
No — it's purely a compile-time feature. The compiled IL is identical. It's a development-time safety net.
Q: What is the ! operator for?
Null-forgiving — tells the compiler "I know this isn't null, stop warning." Use when you have external knowledge the compiler lacks.
10. One-Line Interview Answer
Nullable Reference Types (C# 8+) make reference type nullability explicit at compile time —stringis non-null,string?is nullable — eliminating unexpected NullReferenceExceptions through compiler warnings and flow analysis, with zero runtime overhead.