我确信有一个简单的解释,但无法解决以下问题:
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;
}
}
是因为我设置了“结构”约束吗?
任何解释或建议?
感谢
答案 0 :(得分:4)
不,你使用leftValue.CompareTo(rightValue) == 1
的错误。
相反,请说leftValue.CompareTo(rightValue) > 0
。
众所周知,CompareTo
如果< 0
小于leftValue
则返回rightValue
,0
如果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
,因为29000
是Int32
字符串文字,因此调用int.CompareTo()
方法。
在第二种情况下,您明确指出T
为short
,然后调用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)
编译器在第一个(静态)调用中推断泛型类型。它使用Int32
。 Int32.CompareTo
方法返回1表示大于。
第二,来自Int16
部队T
的来电是Int16
。 Int16.CompareTo
返回两个值*之间的实际差异。 IComparable
下的合法(只需要一个值> 0) - 但不同,以致您的通话失败。
明确地将第一次调用转发给short
也会导致它失败。
*
不,我不知道为什么Int16会以这种方式实现。似乎是“因为它可以”(Byte
表现相同) - 因为你可以在不担心溢出的情况下减去(因为你为结果转换为更宽的类型)。我需要做更多的工作来为Int32
做类似的工作,我认为这不值得付出努力。