C# 8.0 introduced nullable reference types, enabling the compiler to warn about potential null reference exceptions. However, sometimes you know a value isn't null even when the compiler cannot prove it, such as after validation in a helper method or for properties a framework sets after construction.
The null-forgiving operator ! tells the compiler to suppress nullable warnings for a specific expression, asserting that the value is not null despite what static analysis suggests.
Code
csharp
string? GetName() => GetUserInput();
void Process()
{
string? name = GetName();
if (!IsValidName(name))
return;
// IsValidName has no nullable annotations, so the compiler still thinks name might be null
Console.WriteLine(name!.ToUpper()); // ! suppresses warning
}
bool IsValidName(string? name) => !string.IsNullOrWhiteSpace(name) && name.Length < 50;
class OrderPage
{
// Set by the framework before use
public OrderService Service { get; set; } = null!;
}csharp
string GetName() => GetUserInput();
void Process()
{
string name = GetName();
if (!IsValidName(name))
return;
// No warning, but also no null safety
Console.WriteLine(name.ToUpper());
}
bool IsValidName(string name) => !string.IsNullOrWhiteSpace(name) && name.Length < 50;
class OrderPage
{
// No warning, but also no null safety
public OrderService Service { get; set; }
}Notes
- The
!operator has no effect at runtime; it only suppresses compiler warnings - Use sparingly and only when you're certain a value isn't null
- Common scenarios include: after null checks in helper methods the compiler can't see into, properties set later by a framework (
= null!), or when working with legacy code - Annotated helpers such as
string.IsNullOrEmptyalready inform the compiler, so they need no! - Overuse can defeat the purpose of nullable reference types and hide real bugs
- Also called the "null-suppression operator" or "dammit operator"