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) or null (false).
  • Value: Returns the assigned integer if HasValue is true. Accessing this property when the value is null throws an InvalidOperationException.
  • GetValueOrDefault(): Returns the assigned value if present, or the default value of the type (0) if null. 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 true

Which 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?> versus List<Nullable<int>>).
  • Consistency: Modern C# utilizes the ? operator for nullable reference types (such as string?). Using int? 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>.