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.