Módulo 08: Enumeraciones
Objetivos del módulo
- Comprender qué es un
enumy por qué usarlo - Crear y utilizar enumeraciones
- Usar el atributo
[Flags]para combinaciones - Convertir entre enums, enteros y strings
1. ¿Qué es una enumeración?
📘 Concepto: Un
enum(enumeración) es un tipo de dato que contiene un conjunto fijo de constantes con nombre. Se usa para representar opciones cerradas: días de la semana, estados de un pedido, direcciones, etc.
El problema sin enums
// SIN enum: usamos números "mágicos"
int estadoPedido = 2;
if (estadoPedido == 0) Console.WriteLine("Pendiente");
else if (estadoPedido == 1) Console.WriteLine("Procesando");
else if (estadoPedido == 2) Console.WriteLine("Enviado");
else if (estadoPedido == 3) Console.WriteLine("Entregado");
// ¿Qué significa el 2? ¿Y si alguien pone 99? No hay control.
La solución con enums
enum EstadoPedido
{
Pendiente, // 0
Procesando, // 1
Enviado, // 2
Entregado, // 3
Cancelado // 4
}
EstadoPedido estado = EstadoPedido.Enviado;
if (estado == EstadoPedido.Enviado)
{
Console.WriteLine("Tu pedido está en camino");
}
Ventajas:
- Legible:
EstadoPedido.Enviadoes mucho más claro que2 - Seguro: el compilador no permite valores no definidos
- Autocompletado: VS Code te muestra todas las opciones
2. Crear y usar enums
Declaración
// Los enums se declaran FUERA de las funciones (al principio del archivo)
enum DiaSemana
{
Lunes, // 0
Martes, // 1
Miércoles, // 2
Jueves, // 3
Viernes, // 4
Sábado, // 5
Domingo // 6
}
enum Prioridad
{
Baja = 1,
Media = 5,
Alta = 10,
Urgente = 100
}
📘 Concepto: Por defecto, los valores empiezan en 0 y se incrementan de uno en uno. Puedes asignar valores personalizados si lo necesitas.
Uso básico
DiaSemana hoy = DiaSemana.Miércoles;
Console.WriteLine(hoy); // Miércoles
Console.WriteLine((int)hoy); // 2
Prioridad p = Prioridad.Alta;
Console.WriteLine(p); // Alta
Console.WriteLine((int)p); // 10
Enums con switch
Los enums y switch son compañeros ideales:
enum Semaforo { Rojo, Amarillo, Verde }
Semaforo luz = Semaforo.Verde;
switch (luz)
{
case Semaforo.Rojo:
Console.WriteLine("¡PARA!");
break;
case Semaforo.Amarillo:
Console.WriteLine("Precaución, va a cambiar");
break;
case Semaforo.Verde:
Console.WriteLine("Puedes avanzar");
break;
}
// Switch expression (moderno)
string accion = luz switch
{
Semaforo.Rojo => "Parar",
Semaforo.Amarillo => "Precaución",
Semaforo.Verde => "Avanzar",
_ => "Desconocido"
};
3. Conversiones
Entre enum e int
enum Color { Rojo, Verde, Azul }
// enum → int
Color c = Color.Verde;
int numero = (int)c; // 1
// int → enum
Color c2 = (Color)2; // Color.Azul
Console.WriteLine(c2); // Azul
Entre enum y string
// enum → string
Color c = Color.Rojo;
string nombre = c.ToString(); // "Rojo"
// string → enum
Color c2 = Enum.Parse<Color>("Verde");
Console.WriteLine(c2); // Verde
// string → enum (seguro, sin excepción)
if (Enum.TryParse<Color>("Azul", out Color resultado))
{
Console.WriteLine($"Convertido: {resultado}");
}
else
{
Console.WriteLine("Valor no válido");
}
// Ignorar mayúsculas/minúsculas
Enum.TryParse<Color>("rojo", ignoreCase: true, out Color r); // Funciona
4. Métodos útiles de Enum
enum Estacion { Primavera, Verano, Otoño, Invierno }
// Obtener todos los valores
Estacion[] valores = Enum.GetValues<Estacion>();
foreach (Estacion e in valores)
{
Console.WriteLine($"{e} = {(int)e}");
}
// Primavera = 0
// Verano = 1
// Otoño = 2
// Invierno = 3
// Obtener todos los nombres como string
string[] nombres = Enum.GetNames<Estacion>();
Console.WriteLine(string.Join(", ", nombres));
// Primavera, Verano, Otoño, Invierno
// Comprobar si un valor existe
Console.WriteLine(Enum.IsDefined<Estacion>((Estacion)2)); // True (Otoño)
Console.WriteLine(Enum.IsDefined<Estacion>((Estacion)99)); // False
5. Enums con [Flags]: combinación de valores
📘 Concepto: El atributo
[Flags]permite que un enum represente combinaciones de valores, usando operadores de bits. Cada valor debe ser una potencia de 2.
[Flags]
enum Permisos
{
Ninguno = 0, // 0000
Leer = 1, // 0001
Escribir = 2, // 0010
Ejecutar = 4, // 0100
Eliminar = 8, // 1000
// Combinación predefinida
Todos = Leer | Escribir | Ejecutar | Eliminar // 1111 = 15
}
// Combinar permisos con |
Permisos usuario = Permisos.Leer | Permisos.Escribir;
Console.WriteLine(usuario); // "Leer, Escribir"
// Comprobar si tiene un permiso con HasFlag
if (usuario.HasFlag(Permisos.Leer))
{
Console.WriteLine("Puede leer");
}
if (!usuario.HasFlag(Permisos.Ejecutar))
{
Console.WriteLine("No puede ejecutar");
}
// Añadir un permiso
usuario |= Permisos.Ejecutar; // Ahora tiene Leer, Escribir, Ejecutar
// Quitar un permiso
usuario &= ~Permisos.Escribir; // Ahora tiene Leer, Ejecutar
Console.WriteLine(usuario); // "Leer, Ejecutar"
6. Ejemplo práctico: Juego de rol
enum ClasePersonaje { Guerrero, Mago, Arquero, Sanador, Pícaro }
enum Raza { Humano, Elfo, Enano, Orco }
static void MostrarPersonaje(string nombre, ClasePersonaje clase, Raza raza)
{
Console.WriteLine($"╔══════════════════════════╗");
Console.WriteLine($" Nombre: {nombre}");
Console.WriteLine($" Clase: {clase}");
Console.WriteLine($" Raza: {raza}");
Console.WriteLine($" Stats base:");
var (ataque, defensa, magia) = clase switch
{
ClasePersonaje.Guerrero => (15, 12, 3),
ClasePersonaje.Mago => (5, 6, 18),
ClasePersonaje.Arquero => (12, 8, 5),
ClasePersonaje.Sanador => (4, 7, 16),
ClasePersonaje.Pícaro => (10, 6, 8),
_ => (8, 8, 8)
};
int bonoAtaque = raza == Raza.Orco ? 3 : 0;
int bonoMagia = raza == Raza.Elfo ? 3 : 0;
int bonoDefensa = raza == Raza.Enano ? 3 : 0;
Console.WriteLine($" Ataque: {ataque + bonoAtaque}");
Console.WriteLine($" Defensa: {defensa + bonoDefensa}");
Console.WriteLine($" Magia: {magia + bonoMagia}");
Console.WriteLine($"╚══════════════════════════╝");
}
MostrarPersonaje("Aragorn", ClasePersonaje.Guerrero, Raza.Humano);
MostrarPersonaje("Legolas", ClasePersonaje.Arquero, Raza.Elfo);
7. Ejercicios
Ejercicio 1: Menú de restaurante
Crea enums para categorías de platos (Entrante, Principal, Postre, Bebida). El programa muestra un menú, permite elegir categoría y plato, y calcula el total del pedido.
Ejercicio 2: Máquina de estados
Simula un cajero automático con estados: Apagado, Esperando, Autenticando, MenuPrincipal, Retirando, Error. Controla las transiciones válidas entre estados.
Ejercicio 3: Permisos con Flags
Crea un sistema de permisos para una app con [Flags]: Leer, Crear, Editar, Eliminar, Admin. Define roles predefinidos (Visitante=Leer, Editor=Leer | Crear | Editar, Admin=Todos). Permite asignar y comprobar permisos. |
Ejercicio 4: Agenda semanal
Crea una agenda que use el enum DiaSemana. El usuario puede añadir tareas a un día, ver las tareas de un día, y listar todos los días con sus tareas.
Resumen
| Concepto | Ejemplo |
|---|---|
| Declarar enum | enum Color { Rojo, Verde, Azul } |
| Usar | Color c = Color.Rojo; |
| Enum → int | int n = (int)c; |
| Int → enum | Color c = (Color)0; |
| Enum → string | string s = c.ToString(); |
| String → enum | Enum.Parse<Color>("Rojo") |
| String → enum (seguro) | Enum.TryParse<Color>("Rojo", out var c) |
| Todos los valores | Enum.GetValues<Color>() |
| Flags (combinar) | permisos = Perm.A \| Perm.B |
| Flags (comprobar) | permisos.HasFlag(Perm.A) |