Alex Rivera | Logout

Why can I compare sbyte to all the other numeric types *except* ulong?

Asked 2010-12-01T18:24:03.597
25

You can do >, <, ==, etc. comparisons between sbyte and byte, int, uint, short, ushort, long, double, and float. But not ulong.

My brain is exploding. Can anyone explain why sbyte can be compared to uint but not ulong?

public bool sbyte_ulong_compare(sbyte x, ulong y)
{
    return x < y;  // compiler error CS0019
}

Also, using unchecked doesn't make things work any better. Brain melting.

Another edit. This works:

public bool sbyte_ulong_compare(sbyte x, ulong y)
{   
    //
    // returns x < y
    //
    if (x < 0)
        return true;

    if (y > 127)
        return true;

    return ((long)x < (long)y);
}
Edit
Report

1 Answer

20

dthorpe and Jon's answers are close but not quite correct.

The correct reasoning is as follows.

The specification states:

For an operation of the form x op y, where op is a comparison operator, overload resolution is applied to select a specific operator implementation.

OK, what are the operator implementations that overload resolution has to work with? They are:

bool operator <(int x, int y);
bool operator <(uint x, uint y);
bool operator <(long x, long y);
bool operator <(ulong x, ulong y);
bool operator <(float x, float y);
bool operator <(double x, double y);
bool operator <(decimal x, decimal y);

Plus the enum less-than operator for all enumerated types, plus the lifted-to-nullable versions of each of the foregoing.

Overload resolution must first eliminate inapplicable operators, and then from the remaining set of applicable operators, determine the best operator.

The int, uint, long and enum operators (and their lifted forms) are all eliminated because ulong does not implicitly convert to those types.

The uint and ulong operators (and their lifted forms) are all eliminated because sbyte does not implicitly convert to those types.

That leaves

bool operator <(float x, float y);
bool operator <(double x, double y);
bool operator <(decimal x, decimal y);

and their lifted forms. We must now determine the best operator from those six.

What do we mean by "best"? When comparing two operators, the one with the more specific operand types is the better one. By "more specific" I mean that "Tiger" is more specific than "Animal" because all Tigers are convertible to Animal but not all Animals are convertible to Tiger.

Clearly the unlifted forms are better than all of the corresponding lifted forms. A non-nullable ty

answered 2010-12-01T23:17:55.060

Your Answer