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

时间:2016-04-05 12:30:22

标签: c# .net

如果您运行以下代码:

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文档中具有几乎相同描述的方法表现得如此不同?

2 个答案:

答案 0 :(得分:12)

因为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;

一般

唯一重要的事情&#34; CompareTo的返回值是其符号(或者如果它是0)。 &#34;值&#34;是无关紧要的。 CompareTo()的1,5,500,5000,5000000的返回值是相同的。 CompareTo无法用于衡量&#34;距离&#34;数字之间。所以两种实现都是等价的。

完全错误:

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

你必须始终

if (someValue.CompareTo(someOtherValue) < 0)

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

SByte.CompareTo正在实施&#34;无分支&#34;比较(代码中没有if,代码流是线性的。处理器在分支方面存在问题,因此无分支代码可能比分支机构更快<#34;代码,所以这个微优化。显然,SByte.CompareTo可以写成Int32.CompareTo

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

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

  

指向比较两个元素的函数的指针   qsort重复调用此函数以比较两个元素。它应遵循以下原型:

     

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

     

将两个指针作为参数(都转换为const void *)。该函数通过返回(以稳定和传递的方式)来定义元素的顺序:
  返回值含义
  &lt; 0 p1指向的元素在p2
指向的元素之前   0 p1指向的元素等同于p2
指向的元素   &gt; 0 p1指向的元素位于p2

指向的元素之后

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

SByteByteInt16UInt16Char都使用减法&#34;方法&#34;,而{{3} },Int32UInt32Int64都使用if&#34;方法&#34;。

答案 1 :(得分:6)

查看这两种方法的来源,它们的实现方式不同:

public int CompareTo(sbyte value)
{
    return (int)(this - value);
}

VS

public int CompareTo(int value)
{
    if (this < value)
    {
        return -1;
    }

    if (this > value)
    {
        return 1;
    }

    return 0;
 }

但这一切都不重要,因为返回值的符号是您应该检查的唯一内容。