short s;
s = (EitherTrueOrFalse()) ? 0 : 1;
This fails with:
error CS0266: Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?)
Can anyone explain why this is so? The only thing I can think of is that the compiler doesn't look at the second value and doesn't know the range between the two, in the case I wrote something like
short s;
s = (EitherTrueOrFalse()) ? 0 : 65000;
Correct? The only fix is with an ugly cast?
Also, it seems C# does not have a type suffix for the short type. That's a pretty grave oversight IMO. Otherwise, that would've been a solution...
The compiler has an implicit conversion from a constant expression to various primitive types (so long as the value is within the appropriate range), but here the expression isn't constant - it's just an int expression. It's pretty much the same as:
short s;
s = CallSomeMethodReturningInt32();
as far as the compiler is concerned.
There are two options - you could cast the whole expression, or cast each of the latter two operands:
short s = (EitherTrueOrFalse()) ? (short) 0 : (short) 1;
to make the overall expression type short
. In this particular case, it's a pity that there isn't a numeric literal suffix to explicitly declare a short
literal. Apparently the language designers did consider this, but felt it was a relatively rare situation. (I think I'd probably agree.)
The part about implicit constant conversions is from the C# 3.0 spec section 6.1.8:
6.1.8 Implicit constant expression conversions
An implicit constant expression conversion permits the following conversions:
- A constant-expression (§7.18) of type
int
can be converted to type sbyte,byte
,short
,ushort
,uint
, orulong
, provided the value of the constant-expression is within the range of the destination type.- A constant-expression of type
long
can be converted to typeulong
, provided the value of the constant-expression is not negative.
Because the cast is done by the compiler, not at runtime, I wouldn't call it an ugly cast, I would call it a complicated syntax:
s = (EitherTrueOrFalse()) ? (short)0 : (short)1;
I mean, this is the way it is written in C#, even if it looks ugly.
See this blog article. See Marc Gravell's answer on that question.
I guess this has the same reason as this won't compile:
short s1 = GetShort1();
short s2 = GetShort2();
short s3 = s1 + s2;
I.e. that whenever short is used for something, it gets promoted to int.
来源:https://stackoverflow.com/questions/1672774/no-implicit-int-short-conversion-in-ternary-statement