C# Nullable Types

C# Nullable Types

In C#, nullable value types are declared using the ? syntax.

// Define a nullable int value type
int? optionalValue = null;

C# Nullable Value Types

In C#, nullable types represent the absence of a value and help prevent runtime errors by allowing value types like int? or bool? to hold a null value.

int? optionalValue = null;
// Code here that sets optionalValue
// Checking if nullable type has a value
if (optionalValue.HasValue)
{
// Execute here if nullable type has a value
Console.WriteLine(optionalValue.Value); // Output: 5
}
else
{
// Execute here if the nullable type has no value
Console.WriteLine("No value");
}

C# Nullable Operators

In C#, operators for nullable value types include lifted operators, comparison and equality operators, and logical operators, particularly for the bool? type.

// Arithmetic operators with nullable types
int? a = 5;
int? b = null;
int? sum = a + b; // sum is null
// Comparison operators with nullable types
int? a = 5;
int? b = null;
int? c = null;
Console.WriteLine(a == b); // false, 5 is not equal to null
Console.WriteLine(a != b); // true, 5 is not equal to null
Console.WriteLine(b == c); // true, both are null
Console.WriteLine(b != c); // false, both are null
Console.WriteLine(a > b); // false, because b is null
Console.WriteLine(a < b); // false, because b is null
Console.WriteLine(b > c); // false, because both are null
Console.WriteLine(b <= c); // false, comparison with null is always false
// Logical operators with nullable types
// Logical operators for bool?
bool? t = true;
bool? f = false;
bool? n = null;
// Using &
Console.WriteLine(t & t); // true
Console.WriteLine(t & f); // false
Console.WriteLine(t & n); // null
Console.WriteLine(f & n); // false
// Using |
Console.WriteLine(t | f); // true
Console.WriteLine(f | f); // false
Console.WriteLine(t | n); // true
Console.WriteLine(f | n); // null
// Note: && and || don't support bool? types
// The following lines would cause compilation errors:
// Console.WriteLine(t && f);
// Console.WriteLine(t || n);

C# Nullable Reference and Value Types

In C#, reference types inherently support nullable values, while value types do not.

// int (a value type) must be declared nullable with "?" to accept a null value
int? ValueType = null;
// string (a reference type) inherently accepts a null value
string ReferenceType = null;

C# Nullable Reference Types

In C#, reference types can be assigned null by default to avoid null reference exceptions.

// This prevents a compiler warning for a null reference
string? NullString = null;

C# Nullable Type Conversions

In C#, implicit and explicit conversions exist between nullable and non-nullable types.

// Explicit conversion of nullable to non-nullable types
int? nullableInt1 = 5;
int nonNullableInt1 = (int) nullableInt1;
//Implicit conversion non-nullable to nullable types
int nonNullableInt2 = 5;
int? nullableInt2 = nullableInt2;

C# Variable Annotations

In C#, variable annotations explicitly declare the intended null-state for nullable reference types.

// The compiler reads this reference as "not-null"
string NotNull = "";
//The compiler reads this reference with the annotation (?) as "maybe-null"
string? MaybeNull;
//The annotation (!) tells the compiler that the variable is "not-null" supressing warnings
MaybeNull = "";
int a = MaybeNull!.Length;

C# Static Flow Analysis

In C#, static flow analysis determines the null-state at compile time for nullable reference types.

// Compiler may provide warnings if this variable is used before it's assigned a value.
string? NullableString;
// After assigning a value, there are no more warnings.
NullableString = "Value";

C# Null-Conditional Operators

In C#, null-conditional operators (?. and ?[]) safely access members of objects that might be null for both nullable value types and reference types.

// Using the ? null-conditional operator returns null if the refrence is null
string? message = null;
int? incorrectLength = message.Length; // Throws NullReferenceException
// Using ? null-conditional operator safely returns null
int? correctLength = message?.Length; // Returns null
// It can also be used for indexing
char? firstChar = message?[0];

C# Null-Forgiving Operator

In C#, the null-forgiving operator (!) suppresses warnings when the developer knows a value is not null for both nullable value types and reference types.

// The ! tells the compiler that we know the value is not going to be null, suppressing a warning
string? possiblyNull = GetResult();
Console.WriteLine(possiblyNull!.Length); // No warning will occur since ! is used

C# Null-Coalescing Operator

In C#, the null-coalescing operator (??) provides default values for nullable types.

int? a = null;
int? b = a ?? 3; // b is equal to 3 because a is null
a = 5;
b = a ?? 3; // b is now equal to 5

C# Nullable Value Properties

In C#, the System.Nullable<T> structure includes the properties HasValue and Value.

int? optionalValue = 5;
// Use the HasValue property to see if value is null
if (optionalValue.HasValue)
{
// Use the Value property to get the value
Console.WriteLine(optionalValue.Value); // Output: 5
}
else
{
Console.WriteLine("No value");
}

Learn more on Codecademy