c# – 为什么SByte和Int32 CompareTo()方法的行为不同?

如果您运行以下代码:

SByte w = -5;
Console.WriteLine(w.CompareTo(0));

Int32 x = -5;
Console.WriteLine(x.CompareTo(0));

SByte y = 5;
Console.WriteLine(y.CompareTo(0));

Int32 z = 5;
Console.WriteLine(z.CompareTo(0));

然后你得到以下输出:

-5
-1
5
1

为什么这些具有相同名称的方法在MSDN文档中的描述几乎完全相同?

最佳答案
因为SByte.CompareTo()的实现就像

return m_value - value;

所以简单的减法.这是有效的,因为m_value会自动转换为int,并且任何可能的值组合都与int“合法”.

有两个Int32就无法完成,因为例如Int32.MinValue.CompareTo(Int32.MaxValue)将变为Int32.MinValue – Int32.MaxValue,它将在int范围之外,实际上它实现为两个比较:

if (m_value < value) return -1;
if (m_value > value) return 1;
return 0;

一般来说

CompareTo返回值的唯一重要“事物”是它的符号(或者如果它是0). “价值”无关紧要. CompareTo()的返回值1,5,500,5000,5000000是相同的. CompareTo不能用于衡量数字之间的“距离”.所以两种实现都是等价的.

这样做是完全错误的:

if (someValue.CompareTo(someOtherValue) == -1)

你必须永远

if (someValue.CompareTo(someOtherValue) < 0)

为什么SByte.CompareTo以这种方式构建

SByte.CompareTo正在实现“无分支”比较(代码中没有ifs,代码流是线性的).处理器存在分支问题,因此无分支代码可能比“分支”代码更快,因此这种微优化.显然,SByte.CompareTo可以写成Int32.CompareTo.

为什么任何负值等于-1(任何正值等于1)

这可能是直接从C语言派生的东西:qsort函数例如比较项使用用户定义的方法,如:

Pointer to a function that compares two elements.
This function is called repeatedly by qsort to compare two elements. It shall follow the following prototype:

int compar (const void* p1, const void* p2);

Taking two pointers as arguments (both converted to const void*). The function defines the order of the elements by returning (in a stable and transitive manner):
return value meaning
<0 The element pointed to by p1 goes before the element pointed to by p2
0 The element pointed to by p1 is equivalent to the element pointed to by p2
>0 The element pointed to by p1 goes after the element pointed to by p2

.CompareTo如何在其他原始类型中实现?

SByte,Byte,Int16,UInt16,Char都使用减法“方法”,而Int32,UInt32,Int64,UInt64都使用if“方法”.

转载注明原文:c# – 为什么SByte和Int32 CompareTo()方法的行为不同? - 代码日志