14

这不是为了解决任何特定问题。只是一个编译器问题。

为什么以下代码不会导致编译错误?它将引用类型与原始类型进行比较。null 和 false 都必须被解释为编译器进行比较的东西。还是解析器只是简单地扫描这种模式并将其替换为假?

if(null == false) { }
4

3 回答 3

28

这是合法的,因为使用了提升的比较运算符。如果将 abool与 a进行比较null,则boolandnull都会被隐式转换为Nullable<bool>,而比较运算符 forNullable<bool>最终都会被使用。您会收到警告,因为很明显,它总是错误的。

于 2013-05-04T01:16:39.950 回答
15

光辉的回答是正确的。为了更具体地解决您的一些观点:

为什么以下代码不会导致编译错误?

这个问题无法回答;它不会产生错误,因为它是合法代码,但这是重言式。

如果您的问题实际上是“C# 规范的哪一部分使其合法?”,那么这是一个可以回答的问题。关于提升相等运算符的部分使其合法。

它将引用类型与原始类型进行比较。

它不是。首先,避免使用“原始类型”一词;规范没有明确定义它,它在 C# 中不是一个有用的概念。您的意思是说我认为它将引用类型的值与值类型的值进行比较。

其次,这也不对。空字面量不是引用类型或值类型;它不是类型。它可以转换为任何可为空的值类型或任何引用类型,但它本身不是类型。

在这种情况下,null 文字被转换为可为 null 的 bool 类型。

null 和 false 都必须被解释为编译器进行比较的东西。

正确的。它们被解释为可为空的布尔值。

解析器是否只是简单地扫描这种模式并将其替换为假?

不,但这是一个很好的猜测。编译器会将常量折叠true == falsefalse,但它不会进行涉及可空值类型的折叠优化。可以重新设计该语言以支持对具有可为空值类型操作数的操作进行常量折叠;如果可空值类型反事实地出现在版本 1 中,则可能会支持提议的功能。

于 2013-05-04T14:55:17.283 回答
12

语言规范的第 7.10.6 节(引用类型相等运算符)指出:

x == null即使 T 可以表示值类型,也允许构造,并且当 T 是值类型时,结果被简单地定义为 false 。

该规定要求null == falsefalse,而不是编译器错误。

于 2013-05-04T02:15:47.420 回答