比较数字得到不同的结果

时间:2012-02-19 18:37:41

标签: c# comparable

我确信有一个简单的解释,但无法解决以下问题:

     const short amount = 30000;
     bool isGreater =
             ComparableExtensions.IsGreaterThan(amount, 29000); //returns true

     bool isGreaterThan2 = 
     amount.IsGreaterThan<short>(29000);//returns false

      public static class ComparableExtensions
      {
            public static bool IsGreaterThan<T>(this T leftValue, T rightValue) 
            where T : struct, IComparable<T>
            {
                var result = leftValue.CompareTo(rightValue) == 1;
                return result;
            }

      }

是因为我设置了“结构”约束吗?

任何解释或建议?

感谢

4 个答案:

答案 0 :(得分:4)

不,你使用leftValue.CompareTo(rightValue) == 1的错误。

相反,请说leftValue.CompareTo(rightValue) > 0

众所周知,CompareTo如果< 0小于leftValue则返回rightValue0如果leftValue等于rightValue则返回> 0如果leftValue大于rightValue,则{}为1。您不仅可以使用IsGreaterThan<int>检查相等性。

此外,您在两次调用之间看到不同行为的原因是因为在第一种情况下您调用29000因为文字常量Int32将被解释为short,但是在第二种情况下,您明确说出Int16,因此它将被解释为{{1}}。

答案 1 :(得分:0)

查看IComparable的文档以及CompareTo方法的返回值。它声明如果a < b它将返回小于零的值,如果a == b则返回零,如果a > b则返回大于零的值。然而,您要将返回值与1进行比较。无法保证此方法将返回1。你应该这样做:

var result = leftValue.CompareTo(rightValue) > 0;

答案 2 :(得分:0)

当前的short.CompareTo()实现是这样的:

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

虽然int.CompareTo()实现是这样的:

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

在第一种情况下,通用T类型被推断为Int32,因为29000Int32字符串文字,因此调用int.CompareTo()方法。

在第二种情况下,您明确指出Tshort,然后调用short.CompareTo()

正如其他答案已经指出的那样,IComparable<T>规范并不能保证始终返回:

 0 : if the numbers are equal  
-1 : if the number is lower than the other
 1 : if the number is greater than the other

但只是说它必须返回:

0            : if the numbers are equal  
a number < 0 : if the number is lower than the other
a number > 0 : if the number is greater than the other

答案 3 :(得分:0)

编译器在第一个(静态)调用中推断泛型类型。它使用Int32Int32.CompareTo方法返回1表示大于。

第二,来自Int16部队T的来电是Int16Int16.CompareTo返回两个值*之间的实际差异。 IComparable下的合法(只需要一个值> 0) - 但不同,以致您的通话失败。

明确地将第一次调用转发给short也会导致它失败。

*不,我不知道为什么Int16会以这种方式实现。似乎是“因为它可以”(Byte表现相同) - 因为你可以在不担心溢出的情况下减去(因为你为结果转换为更宽的类型)。我需要做更多的工作来为Int32做类似的工作,我认为这不值得付出努力。