Operator behavior mismatch

Next expression ok

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

But when you use it as shown below, a syntax error occurs.

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

It is not possible to implicitly convert the type 'int' to 'short'. Explicit conversion exists (are you skipping listing?)

Can someone explain why this is so?

Is there a difference between matching strings and strings and datetime-to-datetime in a ternary operator, why?

I would be grateful if you could help me.

+52
casting c # conditional-operator int short
Feb 14 '14 at 13:48
source share
3 answers

C # Language Specification, Version 5 , Section 6.1.9:

The implicit conversion of constant expressions allows the following transformations:

  • A constant expression (ยง7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided that the value of the constant expression is within the range of the destination type.

Your first example is a constant expression, because it can be evaluated at compile time. But see Section 7.19 for more details:

In constant expressions, only the following constructions are allowed:

  • Literals (including the null literal).

[...]

  • The predefined +, -, *, /,%, <, โ†’, &, |, ^, &, ||, == ,! =, <,>, <; =, and> = binary operators if each operand is of the type specified above.
  • The operator ?: conditional.
+60
Feb 14 '14 at
source share

I believe that in the first case, the compiler knows that the lines are equal at compile time and therefore optimizes the code only:

short d = 1;

This works because 1 can be assigned to the short variable.

In the second case, optimization cannot happen because the compiler cannot deduce equality at compile time, so it leaves:

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

This will compile:

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

IL (LinqPad) to call short d = ("obj" == "obj")? 12; :

 IL_0001: ldc.i4.1 IL_0002: stloc.0 // d 
+18
Feb 14 '14 at 13:55
source share

"obj" == "obj" can be resolved at compile time; the compiler treats it as

short 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 cannot be resolved at compile time and throws an error.

+4
Feb 14 '14 at 13:52
source share



All Articles