问题描述
为什么在.NET中
null >= null
解析为false,但是
resolves as false, but
null == null
解析为true吗?
在换句话说,为什么 null> = null
不等于 null>空|| null == null
?
In other words, why isn't null >= null
equivalent to null > null || null == null
?
有人有官方答案吗?
推荐答案
此行为在C#规范中定义()在第14.2.7节中(我强调了相关部分):
This behaviour is defined in the C# specification (ECMA-334) in section 14.2.7 (I have highlighted the relevant part):
< > <= >=
如果操作数类型都不是可为空的值类型,如果结果类型
为 bool
。通过向每个操作数类型添加单个?
修饰符来构造提升形式。 如果一个或两个操作数为 null
,则提升后的
运算符将产生值 false
。否则,提升后的运算符将解开
个操作数,并应用基础运算符以生成 bool
结果。
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 value false
if one or both operands are null
. Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the bool
result.
特别是,这并不意味着通常的关系定律; x> = y
并不意味着!(x< y)
。
In particular, this means that the usual laws of relations don't hold; x >= y
does not imply !(x < y)
.
有人问为什么编译器认为这是 int的提升运算符?
首先。我们来看一下。 :)
Some people have asked why the compiler decides that this is a lifted operator for int?
in the first place. Let's have a look. :)
我们从14.2.4开始,即二进制运算符重载解析。这将详细说明要遵循的步骤。
We start with 14.2.4, 'Binary operator overload resolution'. This details the steps to follow.
-
首先,检查用户定义的运算符的适用性。这是通过检查由
> =
每一侧的类型定义的运算符完成的,这引出了null类型是什么的问题
是!实际上,null
文字实际上没有任何类型,只是 null文字。通过遵循14.2.5中的指示,我们发现这里没有合适的运算符,因为null文字没有定义任何运算符。
First, the user-defined operators are examined for suitability. This is done by examining the operators defined by the types on each side of
>=
... which raises the question of what the type ofnull
is! Thenull
literal actually doesn't have any type until given one, it's simply the "null literal". By following the directions under 14.2.5 we discover there are no operators suitable here, since the null literal doesn't define any operators.
此步骤指导我们检查预定义运算符集的适用性。 (本节还排除了枚举,因为双方都不是枚举类型。)相关的预定义运算符在14.9.1至14.9.3节中列出,它们都是原始数字类型的运算符,以及它们的提升版本。这些运算符(请注意,此处不包括 string
s运算符)。
This step instructs us to examine the set of predefined operators for suitability. (Enums are also excluded by this section, since neither side is an enum type.) The relevant predefined operators are listed in sections 14.9.1 to 14.9.3, and they are all operators upon primitive numeric types, along with the lifted versions of these operators (note that string
s operators are not included here).
最后,我们必须使用这些运算符和14.4.2中的规则执行重载解析。
Finally, we must perform overload resolution using these operators and the rules in 14.4.2.
实际上执行此决议将非常繁琐,但是幸运的是有一个捷径。在14.2.6下,给出了一个信息丰富的示例,说明了重载解析的结果,其中指出:
Actually performing this resolution would be extremely tedious, but luckily there is a shortcut. Under 14.2.6 there is an informative example given of the results of overload resolution, which states:
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);
将重载解析规则(第14.4.2节)应用于这组运算符时,其效果是从操作数类型中选择存在隐式转换的运算符
中的第一个。
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
,我们可以立即丢弃所有未使用的运算符。这使我们可以在所有原始数字类型上使用提升的数字运算符。
Since both sides are null
we can immediately throw out all unlifted operators. This leaves us with the lifted numeric operators on all primitive numeric types.
然后,使用前面的信息,我们选择存在隐式转换的第一个运算符。由于null文字可隐式转换为可为null的类型,并且 int
存在可为null的类型,因此我们从列表中选择第一个运算符,即诠释? > = int?
。
Then, using the previous information, we select the first of the operators for which an implicit conversion exists. Since the null literal is implicitly convertible to a nullable type, and a nullable type exists for int
, we select the first operator from the list, which is int? >= int?
.
这篇关于C#可为空的平等操作,为什么null< = null解析为false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!