How it works
A nullable value type adds a missing state to an ordinary value type. For example, int? can contain an integer or null. This is useful when zero is a meaningful observation: a recorded count of zero is different from a count that has not been supplied. The type makes that distinction visible instead of relying on a magic number such as negative one.
Choose the default only at the point where the application has a policy for missing data. The null-coalescing operator returns its right operand when the left is null. It does not treat zero, false, or an empty string as missing. Keeping the original nullable value until that decision allows a report to distinguish unknown observations from real measurements.
Walk through the example. The missing score receives a display fallback of negative one. The recorded zero remains zero when the same operation is applied. A nullable total starts without a value, then receives a real value through assignment. HasValue describes that change, while GetValueOrDefault supplies the underlying type's default for a still-missing value.
Watch the boundary. Reading Value when HasValue is false throws. Replacing every missing measurement with zero can also corrupt averages, minimums, and completion reports without throwing anything. A program can compile and still erase an important domain distinction. Decide whether an absent field should be ignored, rejected, displayed as unknown, or replaced with a documented default.
Practice independently. Create a report for three optional daily readings: one missing, one zero, and one positive. Print an explicit unknown label for the missing entry, then calculate an average from only the recorded entries. Try the all-missing case and define its output deliberately. Finally explain why averaging three defaulted zeros would answer a different question from averaging the observed values.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
int? missing = null;
int? zero = 0;
Console.WriteLine(missing ?? -1);
Console.WriteLine(zero ?? -1);
int? total = null;
Console.WriteLine(total.HasValue);
total = 7;
Console.WriteLine(total.HasValue);
Console.WriteLine(missing.GetValueOrDefault());
Expected output
-1 0 False True 0
Preserve missing data until the calculation or display policy is known.