1. Introducción
En programación muchas veces tienes que trabajar con listas de opciones conocidas y limitadas de antemano. Por ejemplo: días de la semana, colores del semáforo, niveles de dificultad de un juego, estados de un pedido. Cada una de estas opciones normalmente se representa con un valor fijo. Y aquí es donde nos acercamos al tema de hoy — enumeraciones (enum).
Enumeración — es un tipo de dato especial que te permite declarar un conjunto de constantes con nombre.
enum — es como una caja con etiquetas en compartimentos, donde cada etiqueta es un nombre único asociado a un número.
- Tu código se vuelve legible y autodocumentado;
- En vez de números mágicos como 0, 1, 2 aparecen nombres expresivos: DayOfWeek.Monday o TrafficLight.Red;
- El compilador se quejará si intentas asignar un valor incorrecto;
- ¡Detrás de cada elemento hay... un número entero normal! (Pero ya volveremos a eso.)
2. Sintaxis para declarar una enumeración
Vamos a crear nuestra primera enumeración — tipos de clima para nuestra futura app. Así es como se ve:
// Enumeración de condiciones climáticas
public enum WeatherCondition
{
Sunny, // 0
Cloudy, // 1
Rainy, // 2
Stormy, // 3
Snowy // 4
}
- La palabra clave enum define un nuevo tipo.
- Entre llaves — los nombres de las opciones. Por defecto, a cada opción se le asigna un número entero empezando desde cero (Sunny == 0, Cloudy == 1, etc.).
- Puedes asignar valores explícitos:
public enum WeatherCondition
{
Sunny = 1,
Cloudy = 2,
Rainy = 4,
Stormy = 8,
Snowy = 16
}
Esto es útil si los valores tienen que coincidir con algún estándar externo o protocolo.
3. Usando enumeraciones
Imagina que escribimos una app — un pequeño programa de consola que reacciona al clima.
// Clase de la aplicación
class Program
{
static void Main()
{
// Usamos nuestra enumeración para guardar el estado del clima
WeatherCondition todayWeather = WeatherCondition.Sunny;
// Mostramos en pantalla
Console.WriteLine($"El clima de hoy: {todayWeather} ({(int)todayWeather})");
// Ahora simulamos un cambio de clima
todayWeather = WeatherCondition.Rainy;
Console.WriteLine($"¡Ups! El clima cambió: {todayWeather} ({(int)todayWeather})");
}
}
¿Qué va a pasar?
El clima de hoy: Sunny (0)
¡Ups! El clima cambió: Rainy (2)
- todayWeather — no es un string, ni un número, sino un elemento de la enumeración.
- El casteo a (int) te deja ver el “código numérico” de ese valor.
Por cierto, las enumeraciones van genial con condiciones:
if (todayWeather == WeatherCondition.Rainy)
Console.WriteLine("¡Llévate un paraguas!");
4. Escenarios prácticos para usar enum
¿Dónde se ven las enumeraciones?
- En apps de negocio: estados de pedidos (New, Processing, Shipped, Cancelled).
- En sistemas de gestión de usuarios: niveles de acceso (User, Moderator, Admin).
- En juegos: estados del personaje (Idle, Moving, Jumping, Falling).
- En GUI: botones, mensajes, colores de iconos.
Y si te metes en .NET — las vas a encontrar en casi cada clase de la librería estándar. Por ejemplo, para operaciones de archivos hay enumeraciones para indicar el modo de apertura (lectura, escritura, crear).
5. Valores explícitos y rango de valores
A veces quieres convertir un conjunto de valores int que usas en tu código a un enum. Es súper fácil:
public enum CompassDirection
{
North = 10,
East = 20,
South = 30,
West = 40
}
Ahora CompassDirection.North = 10, East = 20, etc. Si algún elemento no tiene valor explícito, automáticamente recibe el valor anterior +1.
Tipo de almacenamiento
Por defecto, enum se guarda como int (un entero de 4 bytes). Pero puedes indicar tu propio tipo base si quieres ahorrar memoria:
public enum TinyEnum : byte
{
First, // 0
Second, // 1
Third // 2
}
¡Ahora cada valor de la enumeración ocupa solo un byte!
Lista completa de tipos posibles: byte, sbyte, short, ushort, int, uint, long, ulong.
6. Conversión entre enum y números/strings
Conversión enum ↔ int:
Para convertir un enum a int y viceversa, simplemente usa typecast:
WeatherCondition current = WeatherCondition.Cloudy;
int number = (int)current; // Obtendrás 1
WeatherCondition fromNumber = (WeatherCondition)2; // Obtendrás Rainy
Conversión enum ↔ string:
Convertir un enum a string es fácil: solo llama al método ToString().
// Convertimos enum a string
string name = WeatherCondition.Stormy.ToString(); // "Stormy"
// Convertimos string a enum usando Enum.Parse
WeatherCondition parsed = (WeatherCondition)Enum.Parse(typeof(WeatherCondition), "Stormy");
// También puedes usar Enum.TryParse
WeatherCondition parsedOk;
if (Enum.TryParse("Snowy", out parsedOk))
{
Console.WriteLine(parsedOk); // Snowy
}
Error típico:
Si casteas un número a enum para el que no hay ningún miembro definido, el compilador no se quejará, pero tendrás un estado “virtual”.
Por ejemplo:
WeatherCondition weird = (WeatherCondition)999;
Console.WriteLine(weird); // 999 (¡no se convertirá en "Unknown"!)
O sea, el programador tiene que estar atento con estas conversiones.
7. switch y enum son el uno para el otro
Las enumeraciones (enum) van genial con el operador switch. Es una forma cómoda y clara de “reaccionar” a los diferentes valores de la enumeración — sin un montón de “if-else”.
Ejemplo: reacción al clima
public enum WeatherCondition
{
Sunny,
Cloudy,
Rainy,
Stormy,
Snowy
}
WeatherCondition today = WeatherCondition.Rainy;
switch (today)
{
case WeatherCondition.Sunny:
Console.WriteLine("¡Soleado! Puedes salir a pasear.");
break;
case WeatherCondition.Cloudy:
Console.WriteLine("Nublado. Puedes llevarte una sudadera.");
break;
case WeatherCondition.Rainy:
Console.WriteLine("Está lloviendo. ¡No olvides el paraguas!");
break;
case WeatherCondition.Stormy:
Console.WriteLine("¡Tormenta! Mejor quédate en casa.");
break;
case WeatherCondition.Snowy:
Console.WriteLine("Está nevando — ¡ponte gorro!");
break;
default:
Console.WriteLine("Clima desconocido...");
break;
}
- Cada caso (case) corresponde a un valor de la enumeración.
- Si el valor no coincide con ninguno de los conocidos, se ejecuta default (útil si por alguna razón llega un valor inesperado).
¿Por qué mola la combinación enum + switch?
- Código legible: ves todas las opciones posibles de una vez en la lista de case.
- Fácil de ampliar: añades un nuevo tipo de clima — solo agregas otro case.
- Seguridad: el compilador te avisa si te olvidas de manejar algún caso (desde C# 8.0 incluso puedes activar la comprobación de exhaustividad).
Ejemplo: enum con lógica para un juego
public enum GameState
{
Start,
Playing,
Paused,
GameOver
}
void PrintState(GameState state)
{
switch (state)
{
case GameState.Start:
Console.WriteLine("¡Bienvenido al juego!");
break;
case GameState.Playing:
Console.WriteLine("El juego está en marcha. ¡Suerte!");
break;
case GameState.Paused:
Console.WriteLine("Pausa. Puedes descansar un poco.");
break;
case GameState.GameOver:
Console.WriteLine("Juego terminado. ¡Inténtalo de nuevo!");
break;
default:
Console.WriteLine("Estado de juego desconocido.");
break;
}
}
Consejos:
- Si tienes muchas acciones parecidas para varias opciones, puedes agruparlas:
switch (today)
{
case WeatherCondition.Rainy:
case WeatherCondition.Stormy:
Console.WriteLine("¡No olvides el paraguas y ropa abrigada!");
break;
}
- No te olvides del default para manejar valores inesperados (por ejemplo, si alguien castea un número a enum directamente).
- Con switch es fácil construir “máquinas de estados”, menús y cualquier sistema con un conjunto fijo de opciones.
8. Enumeraciones y métodos/servicios principales de .NET
.NET te da un montón de métodos útiles para enumeraciones:
- Enum.GetNames(typeof(WeatherCondition)) — obtener todos los nombres.
- Enum.GetValues(typeof(WeatherCondition)) — todos los valores.
- Enum.IsDefined(typeof(WeatherCondition), "Rainy") — saber si existe ese miembro en la enumeración.
- Documentación: System.Enum
Ejemplo de cómo mostrar todas las opciones de clima:
foreach (var name in Enum.GetNames(typeof(WeatherCondition)))
{
Console.WriteLine(name);
}
9. Errores frecuentes y “trampas”
- Usan “números mágicos” en vez de enumeraciones, perdiendo legibilidad.
- No manejan valores que no están definidos en la enumeración (ver el punto sobre castear números).
- Ponen nombres sin sentido a los elementos de la enumeración (Value1, Value2... — y ya nadie recuerda qué significa cada uno).
- Rompen el principio de responsabilidad única — usan una enumeración para cosas que no tienen nada que ver.
La mejor solución: usa siempre enumeraciones cuando tengas un conjunto finito de opciones, y ponles nombres claros y autoexplicativos a los elementos.
GO TO FULL VERSION