没有隐含的int - >三元陈述中的短期转换

时间:2009-11-04 10:00:08

标签: c# ternary-operator implicit-cast

short s;
s = (EitherTrueOrFalse()) ? 0 : 1;

这失败了:

  

错误CS0266:无法隐式   将类型'int'转换为'short'。一个   存在显式转换(是吗?   错过演员?)

任何人都可以解释为什么会这样吗?我唯一能想到的是编译器没有查看第二个值而且不知道两者之间的范围,在我编写类似

的情况下
short s;
s = (EitherTrueOrFalse()) ? 0 : 65000;

正确? 唯一的解决方案是丑陋的演员吗?

此外,似乎C#没有短类型的类型后缀。这是一个非常严重的监督IMO。否则,这将是一个解决方案......

3 个答案:

答案 0 :(得分:11)

编译器具有从常量表达式到各种基本类型的隐式转换(只要该值在适当的范围内),但这里表达式不是常量 - 它只是一个int表达。它几乎与:

相同
short s;
s = CallSomeMethodReturningInt32();

就编译器而言。

有两个选项 - 您可以转换整个表达式,或者转换后两个操作数中的每一个:

short s = (EitherTrueOrFalse()) ? (short) 0 : (short) 1;

使整体表达式类型为short。在这种特殊情况下,遗憾的是没有数字文字后缀来显式声明short文字。显然,语言设计师确实考虑过这一点,但觉得这是一种相对罕见的情况。 (我想我可能也同意。)

关于隐式常量转换的部分来自C#3.0规范部分6.1.8:

  

6.1.8隐式常量表达式转换

     

隐式常量   表达式转换允许   转换后:

     
      
  • 类型的常量表达式(第7.18节)   int可以转换为sbyte类型,   byteshortushortuintulong,   提供了价值   常量表达式属于   目的地类型的范围。
  •   
  • 甲   类型long常量表达式可以   转换为ulong,提供   常量表达式的值   不是消极的。
  •   

答案 1 :(得分:1)

因为强制转换由编译器完成,而不是在运行时,我不会称之为丑陋的演员,我会称之为复杂的语法:

s = (EitherTrueOrFalse()) ? (short)0 : (short)1;

我的意思是,这是用C#编写的方式,即使它看起来很难看。

blog article。 有关该问题,请参阅Marc Gravell's answer

答案 2 :(得分:0)

我想这有同样的原因,因为这不会编译:

short s1 = GetShort1();
short s2 = GetShort2();
short s3 = s1 + s2;

即。每当short用于某事时,它就会被提升为int。