C# Nullable 相等操作,为什么 null <= null 解析为 false? [英] C# Nullable Equality Operations, Why does null &lt;= null resolve as false?

查看:22
本文介绍了C# Nullable 相等操作,为什么 null <= null 解析为 false?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在 .NET 中是这样

Why is it that in .NET

null >= null

解析为 false,但是

resolves as false, but

null == null 

解析为真的?

换句话说,为什么 null >= null 不等价于 null >空 ||null == null?

In other words, why isn't null >= null equivalent to null > null || null == null?

有没有人有正式的答案?

Does anyone have the official answer?

推荐答案

此行为在 C# 规范中定义 (ECMA-334)在第 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.

  1. 首先,检查用户定义的运算符的适用性.这是通过检查由 >=... 每一侧的类型定义的运算符来完成的,这就提出了 null 的类型是什么的问题!null 文字在给定之前实际上没有任何类型,它只是空文字".按照 14.2.5 中的指示,我们发现这里没有合适的运算符,因为空字面量没有定义任何运算符.

  1. 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 of null is! The null 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 的操作符不包括在这里).

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 strings 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:

...考虑二元 * 运算符的预定义实现:

...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);

当重载解析规则(第 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.

然后,使用前面的信息,我们选择存在隐式转换的第一个运算符.由于空字面量可隐式转换为可空类型,并且对于 int 存在可空类型,因此我们从列表中选择第一个运算符,即 int?>= 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# Nullable 相等操作,为什么 null <= null 解析为 false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆