Nullable<int> vs. int? - Is there any difference?

C#.Net

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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 for > Nullable<T>, where T is a value type. > The two forms are interchangeable.

Solution 4 - C#

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.

Solution 5 - C#

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;
      }
   }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZachary ScottView Question on Stackoverflow
Solution 1 - C#LukeHView Answer on Stackoverflow
Solution 2 - C#qqbenqView Answer on Stackoverflow
Solution 3 - C#Steve TownsendView Answer on Stackoverflow
Solution 4 - C#MaciejView Answer on Stackoverflow
Solution 5 - C#RajesView Answer on Stackoverflow