为什么我需要显式转换来缩短三元运算符中的整数字面值?

时间:2014-03-01 13:47:42

标签: c# type-conversion

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)));
}

为什么我需要在三元运算符中为short显式转换整数文字?

4 个答案:

答案 0 :(得分:5)

(bool) ? (short) : (int)表达式的类型为int,即使(int)子表达式是常量且在short范围内。

有一个特殊的例外情况,int可以隐式转换为short,当它是常量且在范围内时,但是您的完整表达式不是常量,因此异常不适用,并且语言设计师从未添加过其他类似的异常,可能是因为它们很少有用。

答案 1 :(得分:3)

其他答案中有很好的想法,但没有一个能够准确描述实际问题。那是因为你发现了一个相当微妙的问题! 2006年,当我第一次在LINQ中使用类型推断工作的条件运算符时,我发现了同样的问题。我可以在这里找到关于这个主题的系列文章:

http://blogs.msdn.com/b/ericlippert/archive/2006/05/24/type-inference-woes-part-one.aspx

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

前两个与条件运算符相关。

答案 2 :(得分:2)

因为没有intshort的隐式对话(如果值为constant且可接受范围,则顺便提一下)。看看Implicit Numeric Conversions Table (C# Reference)

来自?: Operator (C# Reference)

condition ? first_expression : second_expression;
  

first_expression和second_expression的类型必须是   同样,或隐式转换必须存在于一种类型

编辑:hdv与what the actual problem is相关。这是return语句(返回类型)的问题。例如;

var i = x == 0 ?
      1 
      :
      (short)(x * Method((short)(x - 1)));

是一个有效的表达式。但i将是int。由于您的返回类型short,这就是错误的重点。

答案 3 :(得分:1)

使用条件运算符?:时,如果不是隐式转换,则两个表达式必须求值为type

此处intshort之间不会发生隐式转换,因此您需要进行显式转换。

来自MSDN:?: Operator

  

first_expression和second_expression的类型必须是   相同,或者必须存在从一种类型到另一种类型的隐式转换。

修改

<强>解释

规则1:第一个和第二个表达式的类型必须是相同类型或可隐式转换。

从上面的规则

,如果你使用条件写相同的satetement是完全有效的 运营商如下:

var result = ( x == 0 ) ? 1 : (short)(x * Method((short)(x - 1)));

原因:

=&GT;第一个表达式中的常数1是int =&GT;你的第二个表达式结果求值为int。(记住对byte或short的任何算术运算都会使结果为int)

现在因为两个表达式都被计算为int类型,因此您不需要任何转换,编译器也不会强制您进行转换。

现在让我们看看你的问题

  

为什么我需要显式转换来缩短整数文字   三元运算符?

就这么简单,因为你的函数返回类型是short,你需要返回short