为什么null == false不会导致c#中的编译错误?

wei*_*in8 14 c# compiler-construction

这不是解决任何特定问题.只是一个编译问题.

为什么以下代码不会导致编译错误?它将引用类型与基本类型进行比较.必须将null和false都解释为某些东西供编译器进行比较.或者解析器只是扫描这样的模式并用false替换它?

if(null == false) { }
Run Code Online (Sandbox Code Playgroud)

Tej*_*rma 28

这是合法的,因为使用了提升的比较运算符.如果您比较boolnull,无论是boolnull获得隐式转换为Nullable<bool>和比较运营商Nullable<bool>最终被使用.你得到一个警告,因为很明显,它总是错误的.

  • 这是唯一正确的答案. (5认同)
  • 我更喜欢你的答案,因为它解释了_why_它是允许的,_how_它的工作原理.而不只是说明显.顺便说一句,编译器(在优化关闭的调试模式下)甚至不尝试发出它.它只是在代码中发出`false`. (4认同)
  • `false`可能不是可以为空的类型,但是它的类型是`bool`并且`bool`和`bool之间存在隐式转换? (4认同)
  • 另外,这里是Eric Lippert关于这个主题的帖子http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null (4认同)

Eri*_*ert 15

Tejas的回答是正确的.更具体地说明一些要点:

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

这个问题不负责任; 它不会产生错误,因为它是合法代码,但这是一个重言式.

如果您的问题实际上是"C#规范的哪一部分使其合法?",那么这是一个可回答的问题.关于解除平等运营商的部分使其合法化.

它将引用类型与基本类型进行比较.

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

其次,这也不正确.null文字不是引用类型或值类型; 它不属于任何类型.它可以转换为任何可以为null的值类型或任何引用类型,但它本身并不是任何类型.

在这种情况下,null文本将转换为可空的bool类型.

必须将null和false都解释为某些东西供编译器进行比较.

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

解析器只是扫描这样的模式并用false替换它?

不,但这是一个很好的猜测.编译器常数折叠,例如,true == false向下false,但它不执行涉及可空值类型的折叠优化.可以重新设计该语言以支持具有可空值类型操作数的操作的常量折叠; 如果在版本1中具有可反复使用的可空值类型,则可能会支持所提出的功能.


drf*_*drf 12

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

x == null构建体被允许即使Ť可以表示的值的类型,并且将结果简单地定义为假当T是一个值类型.

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

  • 规范的这一部分仅适用于类型参数. (2认同)