三元运算符行为不一致

时间:2014-02-14 13:48:08

标签: c# casting int conditional-operator short

以下表达式可以

short d = ("obj" == "obj" ) ? 1 : 2;

但是当您像下面一样使用它时,会发生语法错误

short d = (DateTime.Now == DateTime.Now) ? 1 : 2;

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

任何人都可以解释为什么会这样吗?

在三元运算符中比较字符串到字符串和datetime到datetime之间有什么区别,为什么?

如果你能帮助我,我将不胜感激。

3 个答案:

答案 0 :(得分:59)

C# language specification, version 5,第6.1.9节:

  

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

     
      
  • 如果constant-expression的值在目标类型的范围内,则int类型的常量表达式(第7.19节)可以转换为类型为sbyte,byte,short,ushort,uint或ulong。 / LI>   

您的第一个示例一个常量表达式,因为它可以在编译时进行评估。但有关详细信息,请参阅第7.19节:

  

在常量表达式中只允许使用以下结构:

     
      
  • 文字(包括空文字)。
  •   

[...]

  
      
  • 预定义的+, - ,*,/,%,<<,>>,&,|,^,&&,||,==,!=,<,> ;,< =和> =二元运算符,前提是每个操作数都是上面列出的类型。
  •   
  • ?:条件运算符。
  •   

答案 1 :(得分:17)

我相信在第一种情况下,编译器知道字符串在编译时是相同的,因此将代码优化为:

short d = 1;

这是有效的,因为1可以分配给short变量。

在第二种情况下,优化不可能发生,因为编译器无法在编译时推断出相等性,因此它会离开:

short d = (DateTime.Now == DateTime.Now) ? (long)1 : (long)2;

这将编译:

short d = (DateTime.Now == DateTime.Now) ? (short)1 : (short)2;

IL(LinqPad)呼叫短d =(“obj”==“obj”)? 1:2;

IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // d

答案 2 :(得分:4)

“obj”==“obj”可以在编译时解决;编译器将其视为

短d = 1;

namespace ConsoleApplication1 {
  class Program {
    static void Main(string[] args) {
      short d = ("obj" == "obj") ? 1 : 2;
    }
  }
}

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
 // Code size       4 (0x4)
 .maxstack  1
 .locals init ([0] int16 d)
 IL_0000:  nop
 IL_0001:  ldc.i4.1
 IL_0002:  stloc.0
 IL_0003:  ret
 } // end of method Program::Main

DateTime.Now == DateTime.Now无法在编译时解析并抛出错误。