c# - operandos - El operador ">" no se puede aplicar a los tipos ''ulong'' e ''int''
el operador== no se puede aplicar a operandos del tipo string (3)
He estado experimentando con esto, usando ILSpy para examinar la salida, y esto es lo que he descubierto.
Obviamente, en tu segundo caso, esto es un error: no puedes comparar un ulong
y un int
porque no hay un tipo al que puedas forzar a ambos. Un ulong
puede ser demasiado grande por long
, y un int
puede ser negativo.
En su primer caso, sin embargo, el compilador es inteligente. Se da cuenta de que const 1
> const 32
nunca es cierto, y no incluye su sentencia if
en la salida compilada. (Debería dar una advertencia para el código inalcanzable). Es lo mismo si define y usa una const int
lugar de un literal, o incluso si emite el literal explícitamente (es decir, (int)32
).
Pero entonces, ¿no es el compilador comparando con éxito un ulong
con un int
, que acabamos de decir que era imposible?
Aparentemente no. Entonces, ¿qué está pasando?
Intenta hacer algo en las siguientes líneas. (Tomar entrada y escribir salida para que el compilador no compile nada.)
const int thirtytwo = 32;
static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > thirtytwo;
Console.WriteLine(gt);
}
Esto se compilará, aunque el ulong
sea una variable, y aunque el resultado no se conozca en el momento de la compilación. Echa un vistazo a la salida en 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 de hecho trata tu const int
como un ulong
. Si haces thirtytwo = -1
, el código no se compila, aunque sabemos que gt
siempre será cierto. El compilador en sí no puede comparar un ulong
con un int
.
También tenga en cuenta que si hace que x
long
lugar de ulong
, el compilador genera 32L
lugar de 32
como un entero, aunque no tenga que hacerlo. (Puedes comparar un int
y un long
en tiempo de ejecución).
Esto indica que el compilador no trata a 32
como un ulong
en el primer caso porque tiene que hacerlo, simplemente porque puede coincidir con el tipo de x
. Es evitar 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 derechos.
Tengo curiosidad por saber por qué el compilador de C # solo me da un mensaje de error para la segunda sentencia if.
enum Permissions : ulong
{
ViewListItems = 1L,
}
public void Method()
{
int mask = 138612833;
int compare = 32;
if (mask > 0 & (ulong)Permissions.ViewListItems > 32)
{
//Works
}
if (mask > 0 & (ulong)Permissions.ViewListItems > compare)
{
//Operator ''>'' cannot be applied to operands of type ''ulong'' and ''int''
}
}
No es el CLR que da este mensaje de error, es el compilador.
En su primer ejemplo, el compilador trata a 32
como ulong
(o un tipo que se puede convertir implícitamente a ulong
por ejemplo, uint
), mientras que en su segundo ejemplo, declaró explícitamente el tipo como int
. No hay una sobrecarga del operador que acepta un ulong
y un int
y, por lo tanto, se obtiene un error del compilador.