Reputation: 3519
static void Main()
{
short x = 3;/* no need explicit casting (short)3 */
Console.WriteLine(Factorial(x));
}
static short Factorial(short x)
{
return x == 0 ?
(short)1 /* need explicit casting (short)1 */
:
(short)(x * Factorial((short)(x - 1)));
}
Why do I need an explicit casting to short
for an integer literal in the ternary operator?
Upvotes: 4
Views: 309
Reputation: 660189
The other answers have good ideas in them but none precisely characterizes the actual problem. That's because you have discovered a rather subtle problem! I discovered the same problem in 2006 when I was first working on the conditional operator in the context of getting type inference working in LINQ. My series of articles on the subject can be found here:
https://learn.microsoft.com/en-us/archive/blogs/ericlippert/type-inference-woes-part-one
http://blogs.msdn.com/b/ericlippert/archive/2006/05/26/type-inference-woes-part-two.aspx
http://blogs.msdn.com/b/ericlippert/archive/2006/05/30/type-inference-woes-part-three.aspx
http://blogs.msdn.com/b/ericlippert/archive/2006/07/18/type-inference-woes-part-four.aspx
The first two are relevant to the conditional operator.
Upvotes: 2
Reputation: 98760
Because there is no implicit conversation from int
to short
(if the value is constant
and acceptable range, there is by the way). Take a look at Implicit Numeric Conversions Table (C# Reference)
From ?: Operator (C# Reference)
condition ? first_expression : second_expression;
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other
EDIT: hdv is right about what the actual problem is. It is the problem with return statement (return type). For example;
var i = x == 0 ?
1
:
(short)(x * Method((short)(x - 1)));
is a valid expression. But i
will be an int
. Since your return type is short
, that's the point of the error.
Upvotes: 2
Reputation: 26209
while using conditional operator ?:
both expressions must evaluate to the same type
if not implicit conversion should be possile.
here there is no implicit conversion can happen between int
to short
so you need explicit conversion.
From MSDN : ?: Operator
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
EDIT:
Explanation:
Rule 1: the types of first and second expression must be either same type or implicitly convertable.
from the above rule it is perfectly valid if you write the same satetement using conditional operator as below:
var result = ( x == 0 ) ? 1 : (short)(x * Method((short)(x - 1)));
Reason:
=> constant 1 in first expression is int
.
=> your second expression result evaluates to int.(remember any arithmetic operations on byte or short makes the outcome as int)
so now as both expressions are evaluated to type int
hence you don't need any casting and compiler does not force you for casting.
Now let us see your question
Why do I need an explicit casting to short for an integer literal in the ternary operator?
it is as simple as that because your function return type is short
you need to return short
Upvotes: 1
Reputation:
The type of a (bool) ? (short) : (int)
expression is int
, even if the (int)
sub-expression is constant and within the range of short
.
There is a special exception where int
can implicitly convert to short
when it is constant and within range, but your full expression isn't constant, so that exception doesn't apply, and the language designers never added other similar exceptions, probably because they would only rarely be useful.
Upvotes: 5