这并不是为了解决任何特定问题。只是一个编译器问题。
为什么下面的代码没有编译错误?它将引用类型与原始类型进行比较。 null 和 false 都必须被解释为某种东西,以便编译器进行比较。或者解析器只是扫描这种模式并将其替换为 false?
if(null == false) { }
这是合法的,因为使用了提升比较运算符。如果将
bool
与 null
进行比较,bool
和 null
都会隐式转换为 Nullable<bool>
,并且最终会使用 Nullable<bool>
的比较运算符。您会收到警告,因为显然它总是错误的。
Tejas 的回答是正确的。 更具体地阐述您的一些观点:
为什么下面的代码没有编译错误?
问题无法回答;它不会产生错误,因为它是合法代码,但这是同义反复。
如果您的问题实际上是“C# 规范的哪一部分使此合法?”,那么这是一个可以回答的问题。关于提升相等运算符的部分使其合法。
它将引用类型与原始类型进行比较。
事实并非如此。首先,避免使用“原始类型”这个词;规范没有明确定义它,并且它在 C# 中不是一个有用的概念。你的意思是我认为它正在将引用类型的值与值类型的值进行比较。
其次,这也不正确。 null 文字不是引用类型或值类型;它不属于任何类型。它可以转换为任何可为空的值类型或任何引用类型,但它本身不属于任何类型。
在这种情况下,null 文字将转换为可为 null 的 bool 类型。
null 和 false 都必须被解释为某种东西,以便编译器进行比较。
正确。它们被解释为可为 null 的布尔值。
解析器只是简单地扫描这种模式并将其替换为 false 吗?
不,但这是一个很好的猜测。编译器会常量折叠,例如,
true == false
下降到false
,但它不会进行涉及可为空值类型的折叠优化。可以重新设计该语言以支持可空值类型操作数的操作的常量折叠;如果可空值类型反事实地出现在第一版中,那么所提议的功能可能会得到支持。
语言规范第 7.10.6 节(引用类型相等运算符)指出:
即使 T 可以表示值类型,也允许
构造,并且当 T 是值类型时,结果简单地定义为 false。x == null
此规定要求
null == false
为 false
,而不是编译器错误。