如果你运行下面的代码:
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 文档中具有几乎相同描述的同名方法的行为如此不同?
最佳答案
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)。 “值(value)”是无关紧要的。 CompareTo()
的1、5、500、5000、5000000的返回值是一样的。 CompareTo
不能用于测量数字之间的“距离”。所以这两种实现是等价的。
这样做完全是错误的:
if (someValue.CompareTo(someOtherValue) == -1)
你必须永远
if (someValue.CompareTo(someOtherValue) < 0)
为什么 SByte.CompareTo
是这样构建的
SByte.CompareTo
正在实现“无分支”比较(代码中没有 if
,代码流是线性的)。处理器有分支问题,因此无分支代码可能比“分支”代码更快,所以这个微优化。显然 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() 方法的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36426429/