Why doesn't incrementing Nullable<int> throw an exception?
C#.NetNullableC# 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
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.