Why doesn't incrementing Nullable<int> throw an exception?

C#.NetNullable

C# Problem Overview


Could you please explain, why does Console.WriteLine write empty line (Console.WriteLine(null) give me compilation error) and why there isn't NullReferenceException (even a+=1 shouldn't raise it)?

int? a = null;
a++; // Why there is not NullReferenceException? 
Console.WriteLine(a); // Empty line

C# Solutions


Solution 1 - C#

You're observing the effects of a lifted operator.

From section 7.3.7 of the C# 5 specification:

> Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following: > > - For the unary operators + ++ - -- ! ~ > a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single ? modifier to the operand and result types. The lifted operator produces a null value if the operand is null. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.

So basically, a++ in this case is an expression with a result of null (as an int?) and the variable is left untouched.

When you call

Console.WriteLine(a);

that's being boxed into object, which converts it to a null reference, which is printed as an empty line.

Solution 2 - C#

Jon's answer is correct but I would add some additional notes.

> Why does Console.WriteLine(null) give a compilation error?

There are 19 overloads of Console.WriteLine and three of them are applicable to a null: the one that takes a string, the one that takes a char[] and the one that takes an object. C# cannot determine which of these three you mean, so it gives an error. Console.WriteLine((object)null) would be legal because now it is clear.

> why does Console.WriteLine(a) write an empty line?

a is a null int?. Overload resolution chooses the object version of the method, so the int? is boxed to a null reference. So this is basically the same as Console.WriteLine((object)null), which writes an empty line.

> Why there is not NullReferenceException on the increment?

Where's the null reference that you are worried about? a is a null int? which is not a reference type to begin with! Remember, nullable value types are value types, not reference types, so don't expect them to have reference semantics unless they are boxed to a reference type. There is no boxing in the addition.

Solution 3 - C#

> Are You incrementing null???

int? a = null;
a++;

This statement simply means null++ i.e. null+1.

As per this document, A nullable type can represent the correct range of values for its underlying value type, plus an additional null value.A Nullable, pronounced "Nullable of Int32," can be assigned any value from -2147483648 to 2147483647, or it can be assigned the null value

Here you are incrementing null, then also it will become null value not 0 or any other integer.

> Why it prints blank instead of error??

when you print a nullable type with null value it prints blank instead of error because you are printing a variable i.e. value of a memory location. which maybe null or any integer.

But when you try to print null using Console.WriteLine(null), as null is not a variable, so it doesn't refer to any memory location. And hence it gives error "NullReferenceException".

> Then how can you print any integer using Console.WriteLine(2); ??

In this case, 2 will gets in memory at temporary location, and the pointer points to that memory location to print.

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
QuestionMaxim ZhukovView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Eric LippertView Answer on Stackoverflow
Solution 3 - C#Laxmikant DangeView Answer on Stackoverflow