Nullable Reference Types
Nullable Reference Types are a modern C# feature that helps developers
identify and prevent possible null reference problems
during development.
A reference type can normally contain a reference to an object or
the value null. Nullable Reference Types allow you to
explicitly communicate whether a reference is expected to contain
a value or may be null.
What is null?
The value null means that a reference does not currently
point to an object.
string name = null;
In projects with nullable reference types enabled, the compiler
can warn that assigning null to a non-nullable
reference may cause a problem.
Enabling Nullable Reference Types
Nullable reference type analysis can be enabled in a project file
using the Nullable setting.
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
Modern .NET project templates commonly enable nullable analysis by default.
Non-Nullable Reference Type
A reference type declared without ? is treated as
non-nullable. The compiler expects it to contain a valid reference.
using System;
string name = "Rahul";
Console.WriteLine(name.Length);
Output
5
Nullable Reference Type using ?
Adding ? after a reference type explicitly indicates
that the reference is allowed to contain null.
string? name = null;
Here, name is intentionally allowed to be null.
Checking for null
Before using a nullable reference, check whether it contains a value.
using System;
string? name = null;
if (name is not null)
{
Console.WriteLine(name.Length);
}
else
{
Console.WriteLine("Name is not available.");
}
Output
Name is not available.
Null-Conditional Operator ?.
The null-conditional operator ?. allows you to access
a member only when the object is not null.
using System;
string? name = null;
int? length = name?.Length;
Console.WriteLine(length);
Output
The result of name?.Length is null because
name is null.
Null-Coalescing Operator ??
The ?? operator provides a default value when the
expression on the left side is null.
using System;
string? name = null;
string displayName = name ?? "Guest";
Console.WriteLine(displayName);
Output
Guest
Null-Coalescing Assignment ??=
The ??= operator assigns a value only when the
variable currently contains null.
using System;
string? name = null;
name ??= "CIIT Student";
Console.WriteLine(name);
Output
CIIT Student
Null-Forgiving Operator !
The null-forgiving operator ! tells the compiler that
you believe an expression will not be null at that point.
using System;
string? name = GetName();
Console.WriteLine(name!.Length);
string? GetName()
{
return "Rahul";
}
! operator does not perform a null check and does
not make a null value non-null at runtime. It only changes compiler
null-state analysis.
Nullable Method Parameters
You can clearly indicate whether a method parameter accepts null.
using System;
void PrintName(string? name)
{
if (name is null)
{
Console.WriteLine("Name is missing.");
return;
}
Console.WriteLine($"Name: {name}");
}
PrintName(null);
Output
Name is missing.Nullable Return Values
A method can use string? as its return type when
it may return null.
using System;
string? FindStudentName(int id)
{
if (id == 1)
{
return "Amit";
}
return null;
}
string? name = FindStudentName(10);
Console.WriteLine(name ?? "Student not found.");
Output
Student not found.Nullable Properties
Model properties can also be marked nullable when a value may legitimately be absent.
using System;
namespace n1
{
public class Student
{
public string Name { get; set; } = "";
public string? Email { get; set; }
}
public class Program
{
static void Main(string[] args)
{
Student student = new Student
{
Name = "Priya",
Email = null
};
Console.WriteLine(student.Email ?? "Email not provided.");
}
}
}
Output
Email not provided.Nullable Reference Types in ASP.NET Core
Nullable reference types are particularly useful in ASP.NET Core applications because API models, database queries, request values, and external data can sometimes contain missing values.
public class StudentDto
{
public string Name { get; set; } = "";
public string? PhoneNumber { get; set; }
public string? Email { get; set; }
} Here, Name is expected to contain a value, while
PhoneNumber and Email are allowed
to be null.
Example: Database Data 👀🫥
Suppose a database contains a student whose phone number is optional. The application can represent this correctly using a nullable reference.
using System;
string? phoneNumber = GetPhoneNumber();
if (phoneNumber is null)
{
Console.WriteLine("Phone number is not available.");
}
else
{
Console.WriteLine($"Phone: {phoneNumber}");
}
string? GetPhoneNumber()
{
return null;
}
Output
Phone number is not available.
Nullable Reference Types vs Nullable Value Types
Nullable reference types and nullable value types are related to null handling but work with different categories of types.
| Nullable Reference Type | Nullable Value Type |
|---|---|
string? |
int? |
| Works with reference types | Works with value types |
| Uses nullable analysis | Uses Nullable<T> |
| Helps detect possible null references | Allows value types to represent null |
Best Practices
- Enable nullable reference type analysis for modern projects.
-
Use
?when a reference is intentionally allowed to be null. - Check nullable values before accessing their members.
-
Use
??when a sensible default value is available. -
Use
?.for safe member access when appropriate. -
Avoid using
!simply to suppress warnings without understanding why the value is safe. - Design method parameters and return types to accurately communicate whether null is allowed.
Common Mistakes
- Ignoring nullable warnings instead of understanding their cause.
-
Using the null-forgiving operator
!everywhere. - Assuming nullable reference types automatically prevent null values at runtime.
- Forgetting to handle null values received from external systems.
- Marking every reference as nullable even when the value should always exist.
Interview Questions
- What are Nullable Reference Types in C#?
- Why were Nullable Reference Types introduced?
- How do you declare a nullable reference type?
- What is the difference between
stringandstring?? - What is the purpose of the null-forgiving operator
!? - What is the difference between
?.and??? - What does
??=do? - Do Nullable Reference Types provide runtime protection?
- How are Nullable Reference Types useful in ASP.NET Core?
- What is the difference between nullable reference types and nullable value types?
Practice Programs
-
Create a program using
string?and safely check a name. - Create a student class with nullable Email and PhoneNumber properties.
-
Use the
??operator to provide a default student name. -
Use the
?.operator to safely access a nullable object's property. - Create a method that may return a nullable student name.
- Create an ASP.NET Core DTO containing both required and optional properties.
Summary
- Nullable Reference Types help identify possible null reference problems.
- A non-nullable reference type indicates that null is not expected.
-
A nullable reference type uses
?. -
The
?.operator provides safe member access. -
The
??operator provides a fallback value. -
The
??=operator assigns a value only when the current value is null. -
The
!operator suppresses nullable warnings but does not perform a runtime null check. - Nullable Reference Types are especially useful in modern ASP.NET Core applications.
- Correct null handling makes applications safer and easier to maintain.