Conversión de int a enum en C#: por qué rompe el código y cómo solucionarlo correctamente
\n\nCada desarrollador de C#, incluso con unos meses de experiencia, tarde o temprano se enfrenta a la pregunta: «How do I cast int to enum in C#?». Esta consulta en Stack Overflow ha acumulado cientos de miles de visitas, y con razón. Parece sencillo: escribes (MyEnum)myInt y listo. Pero el diablo, como siempre, está en los detalles. Una conversión incorrecta de int a enum puede provocar excepciones, errores difíciles de detectar e incluso la caída de un servidor en producción.
En este artículo, analizaremos los 5 errores principales al convertir int a enum, mostraremos ejemplos prácticos en C# y proporcionaremos un algoritmo claro para una conversión segura. Si programas en C# y usas enumeraciones, esta información te ahorrará horas de depuración.
\n\nError n.º 1: Conversión ingenua sin verificación — «¿Y si el número no es válido?»
\n\nLa forma más común que los principiantes encuentran en Internet es el cast directo:
\n\nenum Status\n{\n Active = 1,\n Inactive = 2,\n Pending = 3\n}\n\nint input = 5; // El usuario envió algo incorrecto\nStatus status = (Status)input; // Sin error, pero status == (Status)5\nConsole.WriteLine(status); // Salida: 5 — ¡valor basura!\n\n\nEl código se compilará y ejecutará sin excepción. Pero la variable status ahora contiene el valor 5, que no existe en el enum Status. En C#, las enumeraciones son, en esencia, números enteros con nombres. El compilador no verifica si el valor pertenece al conjunto de constantes. Esta es una trampa clásica: la conversión de int a enum funciona técnicamente, pero lógicamente es un error.
Cómo evitarlo: use siempre el método Enum.IsDefined() antes del cast.
if (Enum.IsDefined(typeof(Status), input))\n{\n Status status = (Status)input;\n}\nelse\n{\n // Manejo de error: registro, valor predeterminado o excepción\n Console.WriteLine($"Valor no válido {input} para Status");\n}\n\n\nRecuerde: Enum.IsDefined() es lento en llamadas frecuentes, pero para operaciones puntuales es un guardián ideal.
Error n.º 2: Ignorar las enumeraciones con banderas ([Flags])
\n\nCuando trabaja con enumeraciones marcadas con el atributo [Flags], la lógica de verificación cambia. Enum.IsDefined() devolverá false para combinaciones de banderas, incluso si son correctas.
[Flags]\nenum Permissions\n{\n None = 0,\n Read = 1,\n Write = 2,\n Execute = 4\n}\n\nint input = 3; // Read + Write\nif (Enum.IsDefined(typeof(Permissions), input))\n{\n // ¡Esto no se ejecutará! 3 no es una constante individual\n}\n\n\nPara las banderas, debe usar otra verificación: si todos los bits en el número corresponden a valores definidos.
\n\nbool IsValidFlags<T>(int value) where T : Enum\n{\n int allValues = 0;\n foreach (var v in Enum.GetValues<T>())\n {\n allValues |= Convert.ToInt32(v);\n }\n return (value & ~allValues) == 0;\n}\n\nif (IsValidFlags<Permissions>(input))\n{\n Permissions perms = (Permissions)input; // Seguro\n}\n\n\nO, más simple, use la verificación incorporada Enum.IsDefined() para cada bandera individual, si son pocas.
Error n.º 3: Olvidar el manejo de números negativos y desbordamiento
\n\nEnum en C# se basa por defecto en int, pero puede ser byte, short, long, etc. Si convierte un int a un enum cuyo tipo base es byte, corre el riesgo de obtener una excepción por desbordamiento o, peor aún, una distorsión silenciosa del valor.
enum SmallEnum : byte\n{\n A = 0,\n B = 255\n}\n\nint bigValue = 300;\nSmallEnum se = (SmallEnum)bigValue; // ¿Error de compilación? ¡No!\n// Pero el valor se truncará: se == (SmallEnum)44 (300 % 256)\n
Blogs
Book Recommendations
Leer también
C++ para programación de sistemas: escribiendo controladores y SO
Cómo obtener nombres de enum en TypeScript: magia bajo el capó
Contenerización de aplicaciones Kotlin con Docker: Guía completa
Secretos de maestría en JavaScript: 9 repositorios de GitHub que transformarán tu código
Despliegue Zero-Downtime en PHP: evita caídas sin dolor