He estado experimentando con esto, usando ILSpy para examinar la salida, y esto es lo que he descubierto.
Obviamente, en su segundo caso, este es un error: no puede comparar un ulong
y un int
porque no hay un tipo al que pueda forzar a ambos. Un ulong
puede ser demasiado grande para un long
, y un int
puede ser negativo.
En su primer caso, sin embargo, el compilador está siendo inteligente. Se da cuenta de que const 1
> const 32
nunca es verdadero, y no incluye su declaración if
en el resultado compilado en absoluto. (Debe dar una advertencia para el código inalcanzable). Es lo mismo si define y usa un const int
en lugar de un literal, o incluso si emite el literal explícitamente (es decir, (int)32
).
Pero entonces no es el compilador de comparando con éxito un ulong
con un int
, que acaba dijimos era imposible?
Aparentemente no. Entonces, ¿qué está pasando?
Intente hacer algo en las siguientes líneas. (Toma de entrada y salida de la escritura por lo que el compilador no compilar nada.)
const int thirtytwo = 32;
static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > thirtytwo;
Console.WriteLine(gt);
}
Esto compilará, a pesar de que la ulong
es una variable, y aunque el resultado no se conoce en tiempo de compilación. Echar un vistazo a la salida de ILSpy:
private static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > 32uL; /* Oh look, a ulong. */
Console.WriteLine(gt);
}
Por lo tanto, el compilador es, de hecho, el tratamiento de su const int
como ulong
. Si realiza thirtytwo = -1
, el código no se compila, aunque sepamos que gt
será siempre verdadero. El compilador no puede comparar un ulong
con un int
.
También tenga en cuenta que si se hace una x
long
en lugar de un ulong
, el compilador genera 32L
en lugar de 32
como un entero, a pesar de que no se tienen a. (Se puede comparar un int
y una long
en tiempo de ejecución.)
Esto apunta a que el compilador no tratar 32
como ulong
en el primer caso porque tiene a, simplemente porque puede coincidir con el tipo de x
. Está evitando que el tiempo de ejecución tenga que forzar la constante, y esto es solo una ventaja cuando la coacción no debería ser posible por derecho.
El motivo de este error es claro. En el segundo ejemplo, intenta realizar una operación ilegal con un número entero. En el primer ejemplo, el '32' se trata como un' ulong'. Deberías hacer que 'mask' sea' ulong'. –
@Ramhound O bien eso (make 'compare' an' ulong'), o make 'compare' una variable' const', por lo que 'const int compare = 32;'. Las expresiones constantes se convertirán felizmente de 'int' a' ulong' en tiempo de compilación si no son negativas, algo que se conoce con el nombre _Conversiones de expresión constante explícita_. –