Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

.net

nullable

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 
like image 569
Maxim Zhukov Avatar asked Mar 20 '15 17:03

Maxim Zhukov


People also ask

What is the difference between nullable int and int?

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.

How do I assign a null to a nullable integer?

As described above, The Nullable types used to assign the null value to the value data type. That means we can assign a null value directly to a variable of the value data type. We can declare null value using Nullable<T> where T is a type like an int, float, bool, etc.

How do you declare a nullable int?

You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, Nullable<int> can be assigned any value from -2147483648 to 2147483647, or a null value.


1 Answers

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.

like image 177
Jon Skeet Avatar answered Oct 13 '22 00:10

Jon Skeet