Nullable types and the ternary operator why is ? 10 null forbidden?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The ternary operator in C# (condition ? whenTrue : whenFalse) requires both branches to resolve to a compatible type. Confusion appears with expressions like condition ? 10 : null, where one branch is an int literal and the other is null. Developers expect implicit nullable conversion, but type inference rules can reject ambiguous cases depending on context.
Understanding how the compiler selects a common type makes these errors predictable and easy to fix. This guide explains the rule and shows explicit patterns that compile cleanly.
Core Sections
1. Why 10 : null can fail
10 is int by default. null has no standalone value type and needs a nullable or reference target type. Without enough context, the compiler cannot always infer that the result should be int?.
The fix is to provide type context explicitly through cast, target typing, or a declared variable type.
2. Use explicit nullable casts
Casting one branch to int? resolves the expression type immediately. This is the most explicit and universally understandable pattern.
3. Use target-typed context when available
When the receiving type is known (int?), the compiler can infer the ternary result. This keeps code concise, but be careful in var declarations where type context may be weaker.
4. Prefer readable alternatives for complex branches
For non-trivial logic, an if block is often clearer than nested ternaries:
Readability matters more than expression compactness, especially when nullable semantics are central to correctness.
5. Build a repeatable validation checklist
Before treating nullable ternary typing in C# as "done", create a small deterministic validation pack that can run in local development, CI, and incident response. The checklist should include at least one happy-path case, one edge case, and one failure-path case with expected behavior documented in plain language. This prevents knowledge from living only in code and reduces onboarding time for new contributors.
A practical validation pack also records environment assumptions explicitly: runtime version, dependency versions, feature flags, and any external services required for the scenario. When those assumptions are visible, debugging becomes much faster because engineers can reproduce the same conditions instead of guessing what changed.
Treat this checklist as a versioned artifact, not a temporary note. Whenever behavior changes, update the checklist in the same pull request. That coupling between implementation and verification is what keeps nullable ternary typing in C# reliable across refactors.
6. Troubleshooting and long-term maintenance
When results diverge from expectations, start from the smallest reproducible case and verify each assumption one layer at a time: inputs, transformation logic, side effects, and output contract. Resist the temptation to patch symptoms quickly; most recurring bugs in nullable ternary typing in C# come from implicit assumptions that were never validated.
Add lightweight observability around the critical path: structured logs, key counters, and clear error categories. In postmortems, capture which signal would have detected the issue earlier, then add that signal permanently. Over time, this creates a maintenance loop where every incident improves the system, instead of repeating the same investigation pattern.
Finally, schedule periodic contract checks even when there is no active incident. Drift accumulates slowly through dependency upgrades, environment changes, and adjacent feature work. Proactive checks keep nullable ternary typing in C# predictable and reduce emergency fixes.
Common Pitfalls
- Assuming
nullautomatically upgrades any value-type branch to a nullable result. - Using
varwith ternaries and expecting inferred nullable type without explicit context. - Nesting ternary expressions until type inference and readability both degrade.
- Forgetting downstream null checks after introducing nullable return values.
- Mixing nullable and non-nullable arithmetic without explicit fallback behavior.
Summary
condition ? 10 : null is about C# type inference, not a random syntax limitation. The compiler needs a clear common type, and giving it explicit nullable context (int?, casts, or typed returns) resolves the issue reliably. Use ternaries for simple expressions, but switch to if statements when logic or nullability rules become hard to read.

