所有"数字"比较器(如Comparer.Default<int>
、Comparer.Default<long>
等(返回-1
、0
或1
,但Comparer.Default<short>
和Comparer.Default<byte>
将返回两个比较数字之间的差值的原因是什么?
它是一个优化功能(返回差值更快(和/或因为两个短或两个字节之间的可能差异将适合int
(Comparer<T>.Compare
返回类型(?但是两个ints
之间的差异不会(例如Comparer<T>.Compare(int.MinValue, int.MaxValue)
(
根据代码中的注释,它是后者:
// Need to use compare because subtraction will wrap // to positive for very large neg numbers, etc.
例如,假设我们有与short
或byte
相同的实现int
:
private int Compare(int x, int y)
{
return x - y;
}
现在,IComparer
合同规定,如果Compare
的结果是:
- 小于零,则 x <y;>
- 大于零,则 x> y;
- 零,则 x == y;
但是,给定上面的实现,如果我们传递一个足够大的负整数作为第一个参数,减法将溢出并包装成一个非常大的正数:
Compare(Int32.MinValue, 1); // returns 2147483647
即结果将错误地指示Int32.MinValue
大于1
。
鉴于IComparer
定义为:
public int Compare (T x, T y);
也就是说,结果类型是int
,只需执行参数的减法short
或byte
是安全的,因为它永远不会导致int
结果溢出。
我认为你完全正确。整数差异不适合整数,但字节差异总是适合。
Compare
的返回值被指定为仅与符号有关。因此,对于较小的类型,返回x
和y
的差异是一种有效且有用的性能优化。
如果你有兴趣:其他语言不一定遵循符号模型(< 0
,0
,> 0
(。有些,例如 Haskell,返回一个枚举,该枚举具有三个可能的值Less, Equal, Greater
。这更干净,但更慢。