Difference Between int? and Nullable<int> in C
In C#, there is no functional difference between int?
and Nullable<int>. The int? syntax is
simply shorthand—known as syntactic sugar—for the underlying generic
struct System.Nullable<int>. Both forms compile to
the exact same Intermediate Language (IL), offer identical performance,
and share the exact same runtime behavior. This article explains how the
compiler treats both representations, how they work under the hood, and
which syntax is preferred in modern C# development.
What Is Nullable<T>?
In C#, value types like int, bool,
double, and DateTime cannot normally hold a
null value; they always contain a default value (such as
0 for an integer). However, database fields, API payloads,
and optional parameters often require representing an unassigned or
missing state.
To solve this, .NET provides the generic struct
System.Nullable<T>, where T must be a
value type. When you declare Nullable<int>, you are
wrapping the standard 32-bit integer inside a structure that can track
whether a value is present or if it represents null.
A Nullable<int> exposes several key members:
HasValue: A boolean property indicating whether the variable contains a valid integer (true) ornull(false).Value: Returns the assigned integer ifHasValueistrue. Accessing this property when the value isnullthrows anInvalidOperationException.GetValueOrDefault(): Returns the assigned value if present, or the default value of the type (0) ifnull. You can also pass an overload with a custom fallback value.
How the Compiler Handles int?
The question mark syntax (int?) was introduced to make
nullable value types cleaner and easier to read. When the C# compiler
encounters int?, it automatically transforms it into
System.Nullable<System.Int32>.
Consider the following two declarations:
int? firstValue = null;
Nullable<int> secondValue = null;When compiled, both variables produce identical bytecode. You can assign values, check for null, and invoke methods identically across both:
int? a = 42;
Nullable<int> b = 42;
bool sameType = typeof(int?) == typeof(Nullable<int>); // Evaluates to trueWhich Syntax Should You Use?
While both syntaxes are interchangeable, int? is
overwhelmingly preferred across the C# community and is enforced by
standard code style rules (such as Microsoft's default Roslyn analyzer
rules).
Using int? offers several advantages:
- Readability and Brevity: It reduces visual clutter,
especially in complex method signatures, LINQ queries, and generic
collections (e.g.,
List<int?>versusList<Nullable<int>>). - Consistency: Modern C# utilizes the
?operator for nullable reference types (such asstring?). Usingint?keeps your code consistent across both value types and reference types.
Unless you are writing reflection logic or documentation where the
explicit type structure must be emphasized, you should always prefer
int? over Nullable<int>.