c# - 奇怪的可空比较行为

标签 c# linq nullable comparator

以下行为背后的合理性(如果有的话)是什么:

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/

相关文章:

linq - 我可以在 LINQ select 子句中声明函数吗?

c# - 如何检测断开连接的套接字 C#?

c# - 当用户尝试打开相同版本的新实例时,如何返回到已打开的应用程序?

c# - .NET DLL 中的 System.DllNotFoundException

json - 检查NewtonSoft JObject C#中是否存在 key

c# - 为什么在没有约束的泛型方法上将可为 null 的值类型与 null 进行比较会比较慢?

c# - 在循环中顺序执行函数而不阻塞ui

c# - Linq联合用法?

C#:可空类型(int?)是对象吗?

c# - 可空类型到底什么时候抛出异常?