以下行为背后的合理性(如果有的话)是什么:
int? a = null;
Console.WriteLine(1 > a); // prints False
Console.WriteLine(1 <= a); // prints False
Console.WriteLine(Comparer<int?>.Default.Compare(1, a)); // prints 1
为什么比较运算符的行为与可空值的默认比较器不同?
更多怪事:
var myList = new List<int?> { 1, 2, 3, default(int?), -1 };
Console.WriteLine(myList.Min()); // prints -1 (consistent with the operators)
Console.WriteLine(myList.OrderBy(i => i).First()); // prints null (nothing) (consistent with the comparator)
Console.WriteLine(new int?[0].Min()); // prints null (nothing)
Console.WriteLine(new int[0].Min()); // throws exception (sequence contains no elements)
最佳答案
<=
和 >
是返回 false
的提升运算符如果任一值为 null
.
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 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.
由于比较器用于排序,因此它们需要总排序,其中 null
根据定义,比较小于所有其他值。这种需要优先于与比较运算符的一致性。比较 null
时返回 0任何其他值都不可能违反传递性,因此设计人员必须选择发出错误,或者总是排序 null
小于或大于任何其他值。在 .net 1 中,他们决定 null
比为引用类型决定的其他所有内容都小,自然地,该决定会延续到 .net 2 中的可为空值类型。
它们之间的区别与 NaN
的区别非常相似表现在 float 上。例如NaN
doesn't 甚至不等于自己,所有比较运算符都返回 false。但是当使用比较器时 NaN
等于自身且小于除null
以外的其他值.
Enumerable.Min
返回最小的非空值,只返回null
如果序列不包含非空值。有这样的功能null
通常代表省略的值,您有兴趣找到最小的实际值。
关于c# - 奇怪的可空比较行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17644983/