usar unario ternario operadores operador como asignacion c# casting int conditional-operator short

unario - operadores de asignacion en c#



Incoherencia del comportamiento del operador ternario (3)

Esta pregunta ya tiene una respuesta aquí:

La siguiente expresión está bien

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

Pero cuando lo usa a continuación, se produce un error de sintaxis

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

No se puede convertir implícitamente el tipo ''int'' en ''corto''. Existe una conversión explícita (¿falta un elenco?)

¿Alguien puede explicar por qué esto es así?

¿Hay alguna diferencia entre comparar string-to-string y datetime-to-datetime en un operador ternario, ¿por qué?

Estaría agradecido si pudieras ayudarme.


"obj" == "obj" se puede resolver en tiempo de compilación; compilador lo trata como

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 no se puede resolver en tiempo de compilación y arroja un error.


Creo que en el primer caso el compilador sabe que las cadenas son iguales en tiempo de compilación y por lo tanto optimiza el código para simplemente:

short d = 1;

Eso funciona porque 1 se puede asignar a la variable short .

En el segundo caso, la optimización no puede suceder porque el compilador no puede inferir la igualdad en tiempo de compilación, por lo que deja:

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

Esto compilará:

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

IL (LinqPad) para call short d = ("obj" == "obj")? 1: 2; :

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


Especificación del lenguaje C #, versión 5 , sección 6.1.9:

Una conversión de expresión constante implícita permite las siguientes conversiones:

  • Una expresión constante (§7.19) de tipo int se puede convertir a tipo sbyte, byte, short, ushort, uint o ulong, siempre que el valor de la expresión constante esté dentro del rango del tipo de destino.

Su primer ejemplo es una expresión constante, porque puede evaluarse en tiempo de compilación. Pero mira la sección 7.19 para más detalles:

Solo las siguientes construcciones están permitidas en expresiones constantes:

  • Literales (incluido el literal nulo).

[...]

  • Los operadores binarios predefinidos +, -, *, /,%, <<, >>, &, |, ^, &&, ||, ==,! =, <,>, <=, Y> =, siempre que cada uno operando es del tipo mencionado anteriormente.
  • El operador condicional?: