tags:

views:

133

answers:

2

In the following:

public class p
{
  short? mID;
  short? dID;
}

short id = p.mID ?? -p.dID.Value;

The compiler gives me the error:

Error 21 Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?)

I have to change the code to the following for it to work:

short id = p.mID ?? (short)-p.dID.Value;

It's as if the compiler is doing something like (int)0 - p.dID.Value, or that Int16.operator - is returning Int32s...?

+6  A: 

I refer you to section 7.6.2 of the specification, which states:


For an operation of the form –x, unary operator overload resolution is applied to select a specific operator implementation. The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. The predefined negation operators are:

Integer negation:

int operator –(int x);
long operator –(long x);

The result is computed by subtracting x from zero. If the value of of x is the smallest representable value of the operand type (−2^31 for int or −2^63 for long), then the mathematical negation of x is not representable within the operand type. If this occurs within a checked context, a System.OverflowException is thrown; if it occurs within an unchecked context, the result is the value of the operand and the overflow is not reported. If the operand of the negation operator is of type uint, it is converted to type long, and the type of the result is long. An exception is the rule that permits the int value −2147483648 (−2^31) to be written as a decimal integer literal .

If the operand of the negation operator is of type ulong, a compile-time error occurs. An exception is the rule that permits the long value −9223372036854775808 (−2^63) to be written as a decimal integer literal .

Floating-point negation:

float operator –(float x);
double operator –(double x);

The result is the value of x with its sign inverted. If x is NaN, the result is also NaN.

Decimal negation:

decimal operator –(decimal x);

The result is computed by subtracting x from zero. Decimal negation is equivalent to using the unary minus operator of type System.Decimal.


As you can see, there is no unary minus operator defined on shorts; overload resolution picks the one on ints because that one is the best match of all the available unary minus operators.

Eric Lippert
Great answer; thanks! I do have to wonder why there is no unary minus operator defined on shorts, though. Any theories?
rabidpebble
+1  A: 

There is no unary minus operator that takes a short value. Instead, the overload resolution chooses the int version of the unary minus operator and does an implicit conversion.

Jeffrey L Whitledge