为什么默认比较器认为 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
与实际值进行比较会给出虚假结果。
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
与实际值进行比较会给出虚假结果。