kiss my armpit
kiss my armpit

Reputation: 3519

Why do I need an explicit casting to short for an integer literal in the ternary operator?

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

Answers (4)

Eric Lippert
Eric Lippert

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

Soner Gönül
Soner Gönül

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

Sudhakar Tillapudi
Sudhakar Tillapudi

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

user743382
user743382

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

Related Questions