为什么默认比较器认为 null 小于一个值

Why does default comparer consider null to be less than a value

Compare(T? x, T? y) 的文档说:

Returns:
A signed integer that indicates the relative values of x and y
Less than zero – x is less than y.
Zero – x equals y.
Greater than zero – x is greater than y.

考虑这个例子:

using System;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine(Comparer<int?>.Default.Compare(null, 1)); // -1   ?huh?
        Console.WriteLine(Comparer<int?>.Default.Compare(-1, 1));   // -1
        Console.WriteLine(Comparer<int?>.Default.Compare(1, 1));    //  0
        Console.WriteLine(Comparer<int?>.Default.Compare(2, 1));    //  1
        
        Console.WriteLine((int?)null < 1);                          // False
        Console.WriteLine((int?)null == 1);                         // False
    }
}

所以 null 比某个值“小”。如果它返回一个不同的幻数(例如 -2),或者抛出异常,或者其他什么,我就不会那么惊讶了。

null < 1如预期的那样是假的,这似乎与上面的相反。

这有什么原因吗,还是只是一个需要注意的 API 怪癖?

它需要根据 IComparable<T> / IComparer<T> 定义比较,并且选择 null 小于还要别的吗。这是指定的 here。唯一的其他选择是抛出异常,大多数人在这里会认为这是一件坏事,因为它会破坏任何带有空值的排序。

< 运算符是 完全独立的 ,并且在任一操作数为 null 时选择了 return false。看起来很不直观:CompareTo< 不需要 完全一致。

这个实验会让你大吃一惊(就像我的一样):

int? a = null;
int b = 0;
if (a < b)
    log.Debug("null is smaller than 0");
else if (a == b)
    log.Debug("null is equal to 0");
else
    log.Debug("null is larger than 0");

输出:null is larger than 0
这并不意味着它更大,它只是意味着它不小 :-) )

但是现在,看看手表中的那些值-window:

a     null   int?
b     0      int
a>b   false  bool
a<b   false  bool
a==b  false  bool

因此,显然,将 null 与实际值进行比较会给出虚假结果。