三元运算符行为不一致
下面的expression是好的
short d = ("obj" == "obj" ) ? 1 : 2;
但是当你像下面一样使用它时,会出现语法错误
short d = (DateTime.Now == DateTime.Now) ? 1 : 2;
不能将types“int”隐式转换为“short”。 存在明确的转换(您是否缺less演员?)
任何人都可以解释为什么这样吗?
为什么在三元运算符中比较string到string和date时间到date时间有什么区别?
如果你能帮助我,我将不胜感激。
C#语言规范,第5版 ,第6.1.9节:
隐式常量expression式转换允许进行以下转换:
- 如果常量expression式的值在目标types的范围内,则可以将inttypes的常量expression式(§7.19)转换为sbyte,byte,short,ushort,uint或ulongtypes。
你的第一个例子是一个常量expression式,因为它可以在编译时进行评估。 但更多细节见7.19节:
在常量expression式中只允许使用以下结构:
- 文字(包括null文字)。
[…]
- 预定义的+, – ,*,/,%,<<,>>,&,|,^,&&,||,==,!=,<,>,<=和> =二元运算符操作数是上面列出的一种types。
- ?:条件运算符。
我相信在第一种情况下编译器知道在编译时string是相等的,因此优化代码只是:
short d = 1;
这是可行的,因为1
可以被分配给short
variables。
在第二种情况下,优化不会发生,因为编译器不能在编译时推断相等性,所以它会留下:
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
“obj”==“obj”可以在编译时parsing; 编译器将其视为
短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在编译时无法parsing并引发错误。