問題描述
為什么在 .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.
首先,檢查用戶定義的運算符的適用性.這是通過檢查由
>=
... 每一側的類型定義的運算符來完成的,這就提出了null
的類型是什么的問題!null
文字在給定之前實際上沒有任何類型,它只是空文字".按照 14.2.5 中的指示,我們發現這里沒有合適的運算符,因為空字面量沒有定義任何運算符.
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
的操作符不包括在這里).
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:
...考慮二元 * 運算符的預定義實現:
...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?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!