C# / Editorial solution guide
Resolve NullReferenceException and Nullable Warnings
Restore the object construction and absence contract rather than suppressing a warning at the eventual dereference.
Read-only knowledge base · No public comments
Recognize the symptoms
A local program throws System.NullReferenceException while accessing a member, or compilation reports CS8602 for a possible null dereference. A null-forgiving ! can remove a warning while the runtime failure remains. The stack location identifies an access, but the absent value may have originated much earlier during construction, lookup, or deserialization.
Understand the likely causes
- Nullable reference annotations drive compile-time analysis; they do not create objects or change string? into a different runtime reference type. Legacy code, external data, default array elements, unchecked constructor paths, or an incorrect annotation can violate the intended non-null contract. Optional absence and missing required state need different fixes.
1. Identify the exact absent value
Preserve the first relevant application stack frame and reduce the failure to a synthetic local input. Break a long access chain into named intermediate values so the null receiver is visible. Trace its assignment and constructor or lookup result. Do not assume the last property name is the cause, and do not replace every access with ?. before deciding what absence means.
2. Treat null-state analysis as contract evidence
Confirm Nullable is enabled in the project and inspect the warning at the earliest inconsistent assignment. A later ! only tells the compiler to trust a claim; it adds no runtime guard. The following deliberately invalid fragment remains non-runnable and has no promised successful output. Fix the source of the missing object or make optionality explicit.
string? name = null;
Console.WriteLine(name!.Length);
This fragment intentionally violates the runtime dereference precondition and must not be executed as a valid example.
3. Separate optional display from required input
The complete example gives an optional display value a documented fallback and validates a required name with a guard. The guard rejects blank or absent input before Trim, and the compiler understands the resulting non-null state. A fallback is appropriate only because this optional field explicitly permits it; a missing required dependency should normally fail construction instead of disappearing silently.
using System;
string? optional = null;
Console.WriteLine($"optional={optional?.Trim() ?? "unknown"}");
Console.WriteLine($"required={RequireName(" Ada ")}");
static string RequireName(string? text)
{
if (string.IsNullOrWhiteSpace(text)) throw new ArgumentException("name required", nameof(text));
return text.Trim();
}
optional=unknown
required=Ada
The optional field prints unknown; the validated required field is trimmed to Ada.
4. Repair constructors and external boundaries
Initialize required members on every successful constructor path and validate deserialized objects before domain use. A new string array still contains null references until populated, despite a non-nullable element annotation. If a Try method communicates non-null output on success, use an accurate contract and suitable nullability attributes rather than a misleading annotation or blanket warning suppression.
Verify the fix
Compile with nullable analysis enabled and inspect the relevant warning resolution without adding !. The complete example must print optional=unknown and required=Ada. Test absent, blank, valid, deserialized-null, and default-array cases under the chosen contract. Verify the intended result or deliberate rejection, not merely that one run avoids an exception.
Keep it from recurring
- Keep required state established at construction, annotate optional data honestly, and review every null-forgiving use against a concrete invariant. Preserve warning checks in normal builds and test legacy/external boundaries. Do not turn all absence into an empty object or string unless the domain explicitly assigns that meaning.