为什么不增加Nullable <int>抛出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节:

提升的操作符允许预定义的和用户定义的操作符在非空值types上操作,也可以使用这些types的可为空的forms。 提升的操作员由预定义的和用户定义的操作员构build,以满足特定的要求,如下所述:

  • 对于一元运算符+ ++ - -- ! ~ 如果操作数和结果types都是非空值types,则存在一个操作符的提升forms。 解除表格是通过添加一个单一的? 修饰符的操作数和结果types。 如果操作数为null,则提升的运算符会生成一个空值。 否则,被解除的操作符展开操作数,应用底层操作符并包装结果。

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

你打电话时

 Console.WriteLine(a); 

被装箱成object ,将其转换为空引用,该空引用被打印为空行。

乔恩的答案是正确的,但我会添加一些额外的笔记。

为什么Console.WriteLine(null)给出编译错误?

Console.WriteLine有19个重载,它们中的三个适用于null :一个接受一个string ,一个接受一个char[]和一个接受objectstring 。 C#不能确定你的这三个意思,所以它给出了一个错误。 Console.WriteLine((object)null)将是合法的,因为现在很清楚。

为什么Console.WriteLine(a)写一个空行?

a是一个空int? 。 重载parsingselect方法的object版本,所以int? 被装箱到空引用。 所以这和Console.WriteLine((object)null)基本相同,它写一个空行。

为什么在增量上没有NullReferenceException

你所担心的空白参考在哪里? a是一个空int? 这不是一个引用types开始! 请记住,可为空的值types是值types ,而不是引用types ,所以不要指望它们具有引用语义,除非它们被装箱到引用types。 除此之外,没有拳击。

你增加空吗?

 int? a = null; a++; 

这条语句只是表示null++即null + 1。

根据这个文档,一个可为空的types可以表示它的基础值types的值的正确范围,加上一个额外的空值。一个可为null的,发音为“Int32的可为空”,可以被赋予-2147483648到2147483647之间的任何值,或者它可以分配空值

在这里,你正在增加null,那么它也将变成空值不是0或任何其他整数。

为什么它打印空白,而不是错误?

当您打印一个null值的可空types时,它将打印空白而不是错误,因为您正在打印一个variables,即内存位置的值。 可能为空或任何整数。

但是当你试图使用Console.WriteLine(null)打印null时,因为null不是一个variables,所以它不会引用任何内存位置。 因此它会给出错误"NullReferenceException"

那么如何使用Console.WriteLine(2);打印任何整数Console.WriteLine(2); ??

在这种情况下,2将在临时位置进入内存,并且指针指向要打印的内存位置。