An int in C# always holds a number. Zero, negative, huge — fine. But "no value at all"? A plain int simply cannot express it, and the compiler stops you the moment you try:
int score = null; // rejected at compile time!
error CS0037: Cannot convert null to 'int' because it is a non-nullable value type
Yet "no value yet" is a real situation: a form field the user skipped, a search that found nothing, a high score before the first game. For those cases C# lets you add a question mark to the type. int? is a nullable value type — it holds either a real int or null:
int? score = 87; // holds a value
int? missing = null; // holds nothing — legal, thanks to the ?
Three tools for working with a nullable:
// 1. HasValue — is anything inside? (safe, never crashes)
score.HasValue // True
missing.HasValue // False
// 2. Value — the raw int inside (only when HasValue is True!)
score.Value // 87
// 3. ?? — the value, or your fallback when null (safe)
missing ?? 0 // 0 — always a plain int, never null
?? is also how you get back to a plain int: writing int x = score; does not compile (error CS0266: Cannot implicitly convert type 'int?' to 'int') — the compiler forces you to decide the null case first, and int x = score ?? 0; is the idiomatic answer.
The trap:
.Value does NOT check for you. Calling it on an empty nullable compiles without a single complaint:
int? missing = null;
Console.WriteLine(missing.Value); // compiles fine...
...and dies the moment it runs:
Unhandled exception. System.InvalidOperationException: Nullable object must have a value.
at System.Nullable`1.get_Value()
The rule: reach for ?? (or check HasValue first) by default, and call .Value only when you have already proven a value is there.
Assignment
Follow the Coding Tutorial and try all three tools on a present and an absent value:
- declare
int? score = 87;andint? missing = null;, - print
HasValuefor each — the safe question, no crash either way, - print
score.Value— safe here, becausescorecertainly holds a value, - print each with the fallback
?? 0.
The exact expected output is:
score has value = True
missing has value = False
score value = 87
score or default = 87
missing or default = 0
Hint
Build each line with string concatenation, e.g. Console.WriteLine("score has value = " + score.HasValue); — C# prints booleans capitalized (True/False). When concatenating a ?? expression, wrap it in parentheses — "score or default = " + (score ?? 0) — because + binds tighter than ??.
Free plan: 30 tutor messages. PRO is unlimited.
