<分区>
为什么是.NET
null >= null
解析为假,但是
null == null
解析为真?
换句话说,为什么 null >= null
不等同于 null > null || null == null
?
有官方的答案吗?
<分区>
为什么是.NET
null >= null
解析为假,但是
null == null
解析为真?
换句话说,为什么 null >= null
不等同于 null > null || null == null
?
有官方的答案吗?
最佳答案
此行为在 C# 规范 ( ECMA-334 ) 的第 14.2.7 节中定义(我已突出显示相关部分):
For the relational operators
< > <= >=
a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is
bool
. The lifted form is constructed by adding a single?
modifier to each operand type. The lifted operator produces the valuefalse
if one or both operands arenull
. Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce thebool
result.
特别是,这意味着通常的关系法则不成立; x >= y
并不意味着 !(x < y)
.
有些人问为什么编译器认为这是 int?
的提升运算符首先。我们来看一下。 :)
我们从 14.2.4“二元运算符重载决议”开始。这详细说明了要遵循的步骤。
首先,检查用户定义的运算符的适用性。这是通过检查由 >=
的每一侧的类型定义的运算符来完成的。 ...这提出了一个问题,即 null
的类型是什么?是! null
在给定一个之前,文字实际上没有任何类型,它只是“空文字”。按照 14.2.5 下的说明,我们发现这里没有合适的运算符,因为 null 文字没有定义任何运算符。
此步骤指示我们检查预定义运算符集的适用性。 (本节也排除了枚举,因为两边都不是枚举类型。)相关的预定义运算符在 14.9.1 到 14.9.3 节中列出,它们都是原始数字类型的运算符,以及提升版本这些运算符(注意此处不包括 string
s 运算符)。
最后,我们必须使用这些运算符和 14.4.2 中的规则执行重载决议。
实际上执行这个决议会非常乏味,但幸运的是有一个捷径。在 14.2.6 下有一个重载决议结果的信息示例,其中指出:
...consider the predefined implementations of the binary * operator:
int operator *(int x, int y); uint operator *(uint x, uint y); long operator *(long x, long y); ulong operator *(ulong x, ulong y); void operator *(long x, ulong y); void operator *(ulong x, long y); float operator *(float x, float y); double operator *(double x, double y); decimal operator *(decimal x, decimal y);
When overload resolution rules (§14.4.2) are applied to this set of operators, the effect is to select the first of the operators for which implicit conversions exist from the operand types.
由于两边都是null
我们可以立即丢弃所有未解除的运算符。这给我们留下了所有原始数字类型的提升数字运算符。
然后,使用先前的信息,我们选择第一个存在隐式转换的运算符。由于 null 文字可隐式转换为可空类型,并且 int
存在可空类型,我们从列表中选择第一个运算符,即 int? >= int?
.
关于C# 可空相等操作,为什么 null <= null 解析为 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4730648/