Nullable<int> vs. int? - Is there any difference?
Apparently Nullable<int>
and int?
are equivalent in value. Are there any reasons to choose one over the other?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
No difference.
int?
is just shorthand for Nullable<int>
, which itself is shorthand for Nullable<Int32>
.
Compiled code will be exactly the same whichever one you choose to use.
While I completely agree that in most cases they are the same, I recently came across a situation, when there is a difference between those two. For the gory details see this question, but to give you a quick example here:
// compiles happily
void Test<T>(T a, bool b)
{
var test = a is Nullable<int> & b;
}
Change Nullable<int>
to int?
(and nothing else):
//does not compile
void Test<T>(T a, bool b)
{
var test = a is int? & b;
}
This second version gives the following error messages:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
If you are curious about the exact reason for this, I really recommend you to check the already linked question, but the basic problem is that in the parsing phase after an is
(or an as
) operator, when we face a ?
token we check if the next token can be interpreted as a unary operator (&
could be one) and if so: the parser doesn't care about the possibility of the ?
token being a type modifier, it simply uses the type before it, and will parse the rest as if the ?
token were a ternary operator (thus the parsing will fail).
So, while in general int?
and Nullable<int>
are interchangeable, there are some corner cases when they produce completely different results, because of how the parser sees your code.
The ?
form is just a shorthand for the full type. Personal preference is the only reason to choose one over the other.
Full details here.
The syntax
T?
is shorthand forNullable<T>
, whereT
is a value type. The two forms are interchangeable.
There apparently is a difference between the two when using code-first Entity Framework (EF) generation:
When your entity contains a property declared like:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF will not generate a nullable property and you will have to force the generator to make it nullable like so:
public class YourContext : DbContext
{
public DbSet<MyEntity> MyEntities{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional();
}
}
On the other hand, if you declare your entity like:
public class MyEntity
{
public int? MyNullableInt { get; set; }
}
the EF generator will property generate a nullable property with a nullable field in the corresponding database table.
Nullable is a generic type, but int? is not.
There are some scenarios where Nullable should be used over int?
for eg: here you cannot replace Nullable with int?
how can you change the below code without using Nullable?
class LazyValue<T> where T : struct
{
private Nullable<T> val;
private Func<T> getValue;
// Constructor.
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
// Execute the delegate.
val = getValue();
return (T)val;
}
}
}