在三元语句中没有隐式int – > short转换

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

这失败了:

错误CS0266:无法将类型’int’隐式转换为’short’。 存在显式转换(您是否错过了演员?)

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

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

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

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

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

 short s; s = CallSomeMethodReturningInt32(); 

就编译器而言。

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

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

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

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

6.1.8隐式常量表达式转换

隐式常量表达式转换允许以下转换:

  • 如果constant-expression的值在目标类型的范围内,则int类型的常量表达式 (第7.18节)可以转换为sbyte, byteshortushortuintulong类型。
  • 如果constant-expression的值不是负数,则long类型的常量表达式可以转换为ulong类型。

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

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

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

请参阅此博客文章 。 请参阅Marc Gravell关于该问题的答案 。

我想这有同样的原因,因为这将无法编译:

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

也就是说,无论什么时候使用short,它都会被提升为int。