C# Null Conditional Operator Not Working Fix
In this tutorial, you'll learn about C# Null Conditional Operator Not Working Fix. We cover key concepts, practical examples, and best practices.
The Problem
You use the null-conditional operator ?. expecting safe navigation, but your code still throws a NullReferenceException or behaves unexpectedly:
var city = person?.Address?.City;
Console.WriteLine(city.ToUpper()); // NullReferenceException
The null-conditional operator short-circuits to null when any member is null, but calling a method on the result without a null check still crashes.
Quick Fix
Step 1: Always follow ?. with a null check or ??
WRONG -- calling methods on the nullable result:
string city = person?.Address?.City;
Console.WriteLine(city.ToUpper());
RIGHT -- use the null-coalescing operator ?? to provide a default:
string city = person?.Address?.City ?? "Unknown";
Console.WriteLine(city.ToUpper());
Step 2: Understand that ?. returns a nullable
WRONG -- assigning to a non-nullable type:
int length = person?.Name?.Length; // CS0266: Cannot implicitly convert int? to int
RIGHT -- use ?? to handle the nullable:
int length = person?.Name?.Length ?? 0;
Or access the nullable value explicitly:
int? length = person?.Name?.Length;
Step 3: Use ?. with method invocations
WRONG -- calling a method on a possibly-null object:
if (person != null)
{
person.Save();
}
RIGHT -- use ?. with method invocation:
person?.Save();
The method is called only if person is not null. This works with Action and Func delegates too:
Action<string> logger = GetLogger();
logger?.Invoke("Log this message");
Step 4: Array and indexer access with ?.
WRONG -- direct indexer access on a null array:
int[] numbers = GetNumbers();
int first = numbers?[0] ?? -1;
RIGHT -- this actually works correctly, but ensure you understand that numbers?[0] returns int?:
int[] numbers = GetNumbers();
int first = numbers?[0] ?? -1;
Step 5: Avoid overuse in event handlers
WRONG -- verbose event invocation pattern:
var handler = OnDataReceived;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
RIGHT -- concise null-conditional invocation:
OnDataReceived?.Invoke(this, EventArgs.Empty);
This is thread-safe because the runtime evaluates ?.Invoke atomically.
Step 6: Beware of value type null propagation
WRONG -- expecting ?. on non-nullable value types to compile:
int value = GetValue();
int? result = value?.ToString(); // value is not nullable
RIGHT -- box to nullable first or use a different approach:
int value = GetValue();
string result = value.ToString();
The ?. operator only works on nullable value types and reference types.
Prevention
- Always pair
?.with??when the result feeds into further operations. - Remember that
?.returns a nullable type for value types. - Use
?.Invokefor event raising to avoid thread-safety issues. - Do not use
?.with non-nullable value types. - Test both null and non-null paths when using
?.in LINQ queries.
Common Mistakes with null conditional
- Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro