null文字的类型是什么?

时间:2011-11-20 20:44:06

标签: c# .net language-lawyer

D 所有人,我想知道C#中null字面的类型是什么?

在Java中,null文字is of the special null type

  

还有一个特殊的 null type ,表达式null的类型,没有名称。由于null类型没有名称,因此无法声明null类型的变量或转换为null类型。空引用是null类型表达式的唯一可能值。 null引用始终可以转换为任何引用类型。

在C ++ 11中,有nullptr(旧好友NULL的推荐版本),is of type std::nullptr_t

我在MSDN上搜索了C#,但specification似乎没有对此说些什么。

3 个答案:

答案 0 :(得分:54)

根据ECMA C# language specification

9.4.4.6空文字:

  

null-literal的类型是null类型(第11.2.7节)。

11.2.7 null类型:

  

null literal(第9.4.4.6节)计算为使用的null值   表示不指向任何对象或数组的引用,或者   没有价值。 null类型有一个值,即   空值。因此,类型为null类型的表达式可以   仅评估空值。没有办法明确写   null类型,因此无法在声明的类型中使用它。   而且,null类型永远不能是类型推断的类型   参数(§25.6.4)

所以要回答你的问题,null是它自己的类型 - null类型。

虽然在C# 4.0 language specificationC# 3.0 language specification中没有提到它,但在overview of C# 3.0ECMA C# language specificationC# 2.0 language specification中提到了它,这很奇怪。 / p>

答案 1 :(得分:44)

更新:This question was the subject of my blog in July 2013.感谢您提出质疑!


J.Kommer的回答是正确的(并且很好地做了显而易见的很多规范挖掘!)但我想我会添加一些历史观点。

当Mads和我正在整理C#3.0规范各部分的确切措辞时,我们意识到“null类型”是奇怪的。它是一个只有一个值的“类型”。这是反射一无所知的“类型”。它是一个“类型”,没有名称,GetType永远不会返回,您不能指定为本地变量或字段的类型或任何东西。简而言之,它实际上是一个“类型”,只有使类型系统“完整”,因此每个编译时表达式都有一个类型。

除了C#已经拥有C#1.0中没有type:方法组的表达式之外,C#2.0中的匿名方法和C#3.0中的lambdas都没有类型。如果所有这些东西都没有类型,我们意识到“null”也不需要类型。因此,我们删除了对C#3.0中无用的“null类型”的引用。

作为一个实现细节,C#1.0到5.0的Microsoft实现都有一个内部对象来表示“null类型”。它们还具有表示不存在的lambda类型,匿名方法和方法组的对象。这种实现选择有许多优点和缺点。在专业方面,编译器可以询问任何表达式的类型并获得答案。另外,这意味着有时类型分析中的错误确实应该使编译器崩溃而导致程序中的语义更改。我最喜欢的例子是在C#2.0中可以使用非法表达式“null ?? null”;由于一个错误,编译器无法将其标记为??运算符的错误用法,并继续推断此表达式的类型是“空类型”,即使它不是空文字。然后继续导致许多其他下游错误,因为类型分析器试图理解类型。

在罗斯林,我们可能不会使用这种策略;相反,我们只是简单地讨论一些表达式没有类型的编译器实现。

答案 2 :(得分:0)

尽管没有运行时类型,但null可以在编译时强制转换为类型,如本例所示。

在运行时,您可以发现变量stringAsObject包含string,而不仅仅是object,但您找不到变量nullString和{{1}的任何类型}}

nullStringAsObject