为什么递增 Nullable<int> 不会抛出异常?

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

你能解释一下,为什么 Console.WriteLine 写空行(Console.WriteLine(null) 给我编译错误)以及为什么没有 NullReferenceException(即使 a+=1 也不应该引发它)?

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

您正在观察提升运算符的效果。

来自 C# 5 规范的第 7.3.7 节:

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.

所以基本上,a++ 在这种情况下是一个结果为 null 的表达式(作为 int?)并且变量保持不变。

当你打电话时

Console.WriteLine(a);

它被装箱到 object 中,将其转换为空引用,打印为空行。

Jon 的回答是正确的,但我会添加一些额外的注释。

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

Console.WriteLine有19个重载,其中三个适用于null:一个string,一个char[]和需要 object 的那个。 C# 无法确定您指的是这三个中的哪一个,因此会报错。 Console.WriteLine((object)null) 是合法的,因为现在很清楚了。

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

a 为空 int?。重载解析选择方法的 object 版本,因此 int? 被装箱到空引用。所以这和Console.WriteLine((object)null)基本一样,都是写一个空行

Why there is not NullReferenceException on the increment?

您担心的 null reference 在哪里? a 是一个 null int? ,它不是引用类型!请记住,可为 null 的值类型是 值类型 ,而不是 引用类型 ,因此不要指望它们具有引用语义,除非它们被装箱到引用类型。加法里面没有装箱

Are You incrementing null???

int? a = null;
a++;

这个语句只是意味着 null++ 即 null+1.

根据本文档,可空类型可以表示其基础值类型的正确值范围,再加上一个额外的空 value.A 可空,发音为 "Nullable of Int32," 可以分配任何值 - 2147483648到2147483647,也可以赋空值

这里你递增null,那么它也会变成null值而不是0或任何其他整数。

Why it prints blank instead of error??

当您打印具有空值的可空类型时,它打印空白而不是错误,因为您正在打印变量,即内存位置的值。可能为 null 或任何整数。

但是当您尝试使用 Console.WriteLine(null) 打印 null 时,因为 null 不是变量,所以它不引用任何内存位置。因此它给出了错误 "NullReferenceException"

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

在这种情况下,2将在临时位置进入内存,指针指向该内存位置进行打印。