C# - Nullables
C# - Handling Null
Section titled “C# - Handling Null”In programming, null represents the absence of a value. Handling null correctly is crucial for writing robust and bug-free applications. C# provides a powerful set of features to manage null, primarily through nullable value types and nullable reference types.
Nullable Value Types (T?)
Section titled “Nullable Value Types (T?)”By default, value types like int, double, bool, and DateTime cannot be null. They must always hold a value. However, sometimes you need to represent an ‘unassigned’ or ‘unknown’ state, for example, a non-required field in a database.
To allow a value type to hold null, you can declare it as a nullable value type by adding a ? after the type name.
Syntax and Usage
Section titled “Syntax and Usage”// A regular int cannot be null// int age = null; // Compile-time error
// A nullable int can be nullint? age = null;
bool? isOptedIn = true;
double? temperature = 21.5;temperature = null; // This is validNullable types have two important properties:
HasValue: A boolean that istrueif the variable holds a value, andfalseif it isnull.Value: Returns the underlying value. Throws anInvalidOperationExceptionif you try to access it whenHasValueisfalse.
int? middleNameLength = null;
if (middleNameLength.HasValue){ Console.WriteLine($"Length is: {middleNameLength.Value}");}else{ Console.WriteLine("No middle name length provided.");}Nullable Reference Types (NRTs)
Section titled “Nullable Reference Types (NRTs)”Introduced in C# 8, Nullable Reference Types (NRTs) are a game-changer for preventing NullReferenceException, one of the most common runtime errors. This feature helps you express your intent about whether a variable (like a string or a custom class object) is allowed to be null.
To enable NRTs, add the following line to your .csproj project file:
<PropertyGroup> <Nullable>enable</Nullable></PropertyGroup>With NRTs enabled:
string name: This is a non-nullable reference type. The compiler will warn you if you don’t initialize it or if you try to assignnullto it.string? nickname: This is a nullable reference type. It is explicitly allowed to benull.
Example with NRTs Enabled
Section titled “Example with NRTs Enabled”#nullable enable // You can also enable this for a single file
string requiredField = "Some value";// requiredField = null; // Generates a compiler warning!
string? optionalField = null; // This is allowed
// Compiler warns you that optionalField might be null here!// Console.WriteLine(optionalField.Length);
// You must check for null before using itif (optionalField != null){ Console.WriteLine(optionalField.Length); // No warning here}Null-Related Operators
Section titled “Null-Related Operators”C# provides several convenient operators for working with nullable types.
Null-Coalescing Operator (??)
Section titled “Null-Coalescing Operator (??)”The ?? operator provides a default value for a nullable type if it is null. It reads as “if the left-hand side is not null, use it; otherwise, use the right-hand side.”
string? userName = null;
// If userName is null, use "Guest". Otherwise, use userName's value.string displayName = userName ?? "Guest";
Console.WriteLine(displayName); // Output: GuestNull-Coalescing Assignment Operator (??=)
Section titled “Null-Coalescing Assignment Operator (??=)”The ??= operator (C# 8+) assigns the right-hand value to the left-hand variable only if the left-hand variable is null.
List<int>? numbers = null;
// If numbers is null, create a new list and assign it to numbers.numbers ??= new List<int>();
numbers.Add(42);Console.WriteLine(numbers.Count); // Output: 1Null-Conditional Operators (?. and ?[])
Section titled “Null-Conditional Operators (?. and ?[])”The ?. and ?[] operators (C# 6+) allow you to access members or elements of a variable only if that variable is not null. If the variable is null, the expression short-circuits and returns null.
string? name = null;
// If name is null, length will be null. Otherwise, it will be name.Length.int? length = name?.Length;Console.WriteLine(length); // Output: (nothing, because length is null)
name = "Alice";length = name?.Length;Console.WriteLine(length); // Output: 5
// Works with arrays and indexers toostring[]? names = { "Alice", "Bob" };string? first = names?[0]; // "Alice"
names = null;first = names?[0]; // first becomes null, no exception is thrownBest Practice
Section titled “Best Practice”Always enable Nullable Reference Types in your modern C# projects. It is one of the single most effective features for improving code quality and preventing runtime errors.