为什么不增加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[]
和一个接受object
的string
。 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将在临时位置进入内存,并且指针指向要打印的内存位置。