Why is CompareTo on short implemented this way?
Consider the following code:
namespace ConsoleApplication1 {
class Program
{
static void Main(string[开发者_C百科] args)
{
Console.WriteLine(100.CompareTo(200)); // prints -1
Console.WriteLine(((decimal)100).CompareTo((decimal)200)); // prints -1
Console.WriteLine(((short)100).CompareTo((short)200)); // prints -100
Console.WriteLine(((float)100).CompareTo((float)200)); // prints -1
Console.ReadKey();
}
}
}
My question is, are there any specific reasons the CompareTo-method on Int16 returns values other than -1, 0 and 1?
ILSpy shows it is implemented this way
public int CompareTo(short value)
{
return (int)(this - value);
}
whereas the method is implented on Int32 this way
public int CompareTo(int value)
{
if (this < value)
{
return -1;
}
if (this > value)
{
return 1;
}
return 0;
}
The difference is that for short
, there's no chance of the result overflowing. For instance, short.MinValue - (short) 1
is still negative - whereas int.MinValue - 1
is int.MaxValue
.
In other words, the specific reason is that you can get away with a shortcut with short
(no pun intended) whereas the same shortcut doesn't work with int
. You should definitely not require IComparable<T>.CompareTo
implementations to return -1, 0 or 1. The documentation is pretty clear that the result is only meaningful in terms of being negative, zero, or positive.
Well, you should only really check the sign anyway, but for reasons: I guess for int
etc there would be a risk of overflow/wrap (when handling 2 large-magnitude numbers) that would reverse the sign, meaning it must check the operators.
I'd rather it was consistent, but it doesn't seem to be a problem. More likely an optimisation that is atypical but within the documented API. In particular, optimising short
here doesn't feel like it is going to get a massive amount of use (I use short
, but not anything like as much as I do int
).
精彩评论