比较数字得到不同的结果
我确信有一个简单的解释,但无法解决以下问题:
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;
}
}
是因为我设置了“结构”约束吗?
有什么解释或建议吗?
谢谢
I am sure that there is a simple explanation but cannot work out the following:
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;
}
}
Is it because i put a "Struct" contraint?
any explanation or suggestions?
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,您使用
leftValue.CompareTo(rightValue) == 1
时犯了错误。相反,请说
leftValue.CompareTo(rightValue) > 0 。
您只知道
CompareTo
返回<如果
;如果leftValue
小于rightValue
,则为 0leftValue
等于rightValue
,则为0
代码>和<代码>>如果leftValue
大于rightValue
,则为 0。您不仅可以检查与1
是否相等。此外,您在两个调用之间看到不同行为的原因是因为在第一种情况下您调用
IsGreaterThan
因为文字常量29000
将被解释为 < code>Int32,但在第二种情况下,您明确地说short
,因此它将被解释为Int16
。No, your mistake using
leftValue.CompareTo(rightValue) == 1
.Instead, say
leftValue.CompareTo(rightValue) > 0
.All you know is that
CompareTo
returns< 0
ifleftValue
is less thanrightValue
,0
ifleftValue
equalsrightValue
and> 0
ifleftValue
is greater thanrightValue
. You can not only check for equality with1
.Additionally, the reason that you see different behavior between the two calls is because in the first case you are calling
IsGreaterThan<int>
because the literal constant29000
will be interpreted asInt32
, but in the second case you explicitly sayshort
so it will be interpreted asInt16
.查看
IComparable
的文档以及CompareTo
方法的返回值。它指出如果a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a < b
,如果a == b
则恰好为零,如果a > 则大于零。 b.
。然而,您正在将返回值与1
进行比较。无法保证此方法将返回1
。你应该这样做:Look at the documentation for
IComparable
, and the return value of theCompareTo
method. It states that it will return a value less than zero ifa < b
, exactly zero ifa == b
, and a value greater than zero ifa > b
. Yet you are comparing the return value to1
. There is no guarantee this method will ever return1
. You should instead do:当前的
short.CompareTo()
实现是这样的:而
int.CompareTo()
实现是这样的:在第一种情况下,通用的
T
类型被推断为Int32
,因为29000
是Int32
字符串文字,因此int.CompareTo() 方法被调用。
在第二种情况下,您明确表示
T
是short
,然后调用short.CompareTo()
。正如其他答案已经指出的那样,
IComparable
规范并不保证始终返回:而只是说它必须返回:
The current
short.CompareTo()
implementation is something like this:while the
int.CompareTo()
implementation is something like this:In the first case the generic
T
type is inferred asInt32
because29000
is anInt32
string literal and so theint.CompareTo()
method is called.In the second case you're specifically saying that
T
isshort
and then theshort.CompareTo()
is called.As other answers already pointed out,
IComparable<T>
specification doesn't assure to return always:but just says that it must return:
编译器在第一次(静态)调用中推断泛型类型。它使用
Int32
。Int32.CompareTo
方法返回 1 表示大于。在第二个例子中,来自
Int16
的调用强制T
为Int16
。Int16.CompareTo
返回两个值之间的实际差异*。在IComparable
下合法(只需要值 > 0) - 但不同之处足以导致您的调用失败。将第一个调用显式转换为
short
也会导致它失败。*
不,我不知道为什么 Int16 是这样实现的。似乎是“因为它可以是”(Byte
的行为相同) - 因为您可以进行减法而不用担心溢出(因为您正在将结果转换为更广泛的类型)。对 Int32 做类似的事情需要更多的工作,我认为这不值得。The compiler infers the generic type in the first (static) call. It uses
Int32
. TheInt32.CompareTo
method returns 1 for greater than.In the second, your call from an
Int16
forcesT
to beInt16
.Int16.CompareTo
returns the actual difference between the two values*. Legal underIComparable
(which only requires a value > 0) - but different enough for your call to fail.Explicitly casting the first call to
short
will cause it to fail as well.*
No, I have no idea why Int16 is implemented that way. Seems to be "because it can be"(Byte
behaves the same) - since you can subtract without fear of overflow (since you're casting to a wider type for the result). It'd require more work to do something similar forInt32
which I suppose wasn't worth the effort.