你能解释一下,为什么Console.WriteLine写空行(Console.WriteLine(null)
给了我编译错误),为什么没有NullReferenceException (即使是a+=1
也不应该抛出它)?
int? a = null;
a++; // Why there is not NullReferenceException?
Console.WriteLine(a); // Empty line
发布于 2015-03-21 01:38:36
您正在观察提升运算符的效果。
从C# 5规范的7.3.7节中:
提升运算符允许对不可为空值类型进行操作的预定义和用户定义运算符也可与这些类型的可为空形式一起使用。提升运算符由满足特定要求的预定义运算符和用户定义运算符构造而成,如下所述:
如果操作数和结果类型都是不可为空值类型,则存在
+ ++ - -- ! ~
unary运算符和提升形式的运算符。提升的形式是通过向操作数和结果类型添加一个?
修饰符来构造的。如果操作数为空,则提升的运算符将生成空值。否则,提升的运算符将展开操作数,应用基础运算符,然后包装结果。因此,基本上,本例中的a++
是一个结果为null
(作为int?
)的表达式,而变量保持不变。
当你调用
Console.WriteLine(a);
它被装箱到object
中,后者将其转换为空引用,并将其打印为空行。
发布于 2015-03-21 02:16:08
Jon的回答是正确的,但我想补充一些补充说明。
为什么
Console.WriteLine(null)
会出现编译错误?
Console.WriteLine
有19个重载,其中三个重载适用于null
:接受string
的重载、接受char[]
的重载和接受object
的重载。C#无法确定您所指的是这三个中的哪一个,因此它会给出一个错误。Console.WriteLine((object)null)
将是合法的,因为现在它是明确的。
为什么
Console.WriteLine(a)
会写一个空行?
a
为空int?
。重载解析选择方法的object
版本,因此int?
被装箱为空引用。所以这基本上和Console.WriteLine((object)null)
是一样的,它写一个空行。
为什么增量上没有
NullReferenceException
?
您担心的空引用在哪里?a
是一个空int?
,从一开始就不是引用类型!请记住,可为空的值类型是值类型,而不是引用类型,因此不要期望它们具有引用语义,除非它们被装箱为引用类型。加法中没有装箱。
发布于 2015-04-14 21:15:20
您是否正在递增null?
int? a = null;
a++;
这句话的意思就是null++
,即null+1。
根据本文档,可空类型可以表示其基础值类型的值的正确范围,外加附加的空值。可以为可空类型分配从-2147483648到2147483647的任何值,也可以为其分配空值,发音为“Nullable of Int32”
在这里你递增null,然后它也将变成null value not 0或任何其他整数。
为什么打印空白而不是错误??
当您使用null值打印一个可空类型时,它会打印空白而不是错误,因为您打印的是一个变量,即内存位置的值。它可以是null,也可以是任意整数。
但是当您尝试使用Console.WriteLine(null)
打印null时,因为null不是一个变量,所以它不会引用任何内存位置。因此它会给出错误"NullReferenceException"
。
那么,如何使用Console.WriteLine(2);
打印任意整数呢??
在这种情况下,2将在内存中的临时位置获取,并且指针指向要打印的内存位置。
https://stackoverflow.com/questions/29172558
复制相似问题