En la lección anterior viste cómo repetir acciones con bucles; antes, aprendiste a tomar
decisiones con if/else if/else. Sin embargo, cuando una misma variable debe compararse
contra muchos valores posibles —por ejemplo, clasificar un libro de BiblioTech según su
categoría: "Novela", "Ensayo", "Poesía", "Infantil", "Ciencia"—, encadenar else if una y
otra vez se vuelve repetitivo y difícil de leer. La sentencia switch resuelve exactamente
ese caso: compara una expresión contra una lista de valores posibles y ejecuta el bloque que
coincida, con una sintaxis más clara y ordenada.
Contenido
- La sentencia
switchclásica case,defaulty la importancia debreak- Varios valores para un mismo
case switchvsif/else if/else- Un vistazo al futuro: switch expressions y pattern matching
- Aplicación completa: clasificar un libro por categoría
- La sentencia
switch clásica
switch clásicaUn switch evalúa una expresión una sola vez y compara su resultado contra una serie de
valores constantes, cada uno definido en una etiqueta case.
string categoria = "Novela";
switch (categoria)
{
case "Novela":
Console.WriteLine("Seccion de narrativa - Planta 1");
break;
case "Ensayo":
Console.WriteLine("Seccion de no ficcion - Planta 2");
break;
case "Poesia":
Console.WriteLine("Seccion de poesia - Planta 1");
break;
default:
Console.WriteLine("Categoria no reconocida - consultar con el bibliotecario");
break;
}Estructura de la sentencia:
switch (expresion): la expresión se evalúa una única vez; puede ser de tipostring, cualquier tipo numérico entero,char,bool, o unenum(que se verá con detalle en módulos posteriores).- Cada
case valor:define una posible coincidencia. Siexpresion == valor, se ejecuta el bloque de código correspondiente. default:se ejecuta si ninguno de loscaseanteriores coincide. Es equivalente alelsefinal de una cadenaif/else if/else, y aunque técnicamente es opcional, se recomienda incluirlo siempre para cubrir casos inesperados.
case, default y la importancia de break
case, default y la importancia de breakA diferencia de otros lenguajes, en C# cada bloque case debe terminar de forma explícita
—normalmente con break— antes de pasar al siguiente. Si un case no contiene ninguna
instrucción que termine el bloque (break, return, throw, o continuar con goto case),
el compilador da un error: C# no permite el "fall-through implícito" (caer de un case al
siguiente sin querer) que sí existe en lenguajes como C o Java.
Para uso cotidiano, basta con recordar la regla simple: todo case debe cerrarse con
break (o con return si el switch está dentro de un método que debe devolver un valor).
string categoria = "Comic";
switch (categoria)
{
case "Novela":
Console.WriteLine("Narrativa");
break;
case "Comic":
Console.WriteLine("Comic y novela grafica");
break; // obligatorio: sin este break, el codigo no compila
default:
Console.WriteLine("Sin clasificar");
break;
}| Elemento | Obligatorio!= | Función |
|---|---|---|
switch (expr) |
Sí | Abre la estructura y define qué se va a comparar |
case valor: |
Al menos uno (o default) |
Define un posible valor de coincidencia |
break; |
Sí (por cada case con código) |
Termina el bloque y sale del switch |
default: |
Recomendado, no obligatorio | Cubre cualquier valor no contemplado en los case |
- Varios valores para un mismo
case
caseCuando varios valores distintos deben provocar exactamente la misma acción, se pueden
"apilar" varias etiquetas case seguidas, sin código entre ellas, antes del bloque común:
string categoria = "Infantil";
switch (categoria)
{
case "Infantil":
case "Juvenil":
Console.WriteLine("Seccion familiar - Planta baja");
break;
case "Novela":
case "Ciencia Ficcion":
case "Fantasia":
Console.WriteLine("Seccion de narrativa - Planta 1");
break;
case "Ensayo":
case "Historia":
case "Ciencia":
Console.WriteLine("Seccion de no ficcion - Planta 2");
break;
default:
Console.WriteLine("Categoria no reconocida");
break;
}Aquí, tanto "Infantil" como "Juvenil" ejecutan el mismo bloque, porque C# permite "apilar"
etiquetas case sin break intermedio: solo el último case del grupo lleva el código y el
break. Esto es distinto del fall-through prohibido: apilar etiquetas vacías está permitido
porque no hay código entre ellas que se "salte" por error.
switch vs if/else if/else
switch vs if/else if/else| Aspecto | switch |
if/else if/else |
|---|---|---|
| Comparaciones | Igualdad exacta contra valores constantes | Cualquier condición booleana, incluidos rangos |
| Legibilidad con muchos valores | Alta: cada caso es una línea clara | Baja: se repite la misma variable muchas veces |
Rangos (paginas > 100 && paginas < 300) |
No directamente (requiere trucos avanzados) | Sí, de forma natural |
| Tipos admitidos | string, enteros, char, bool, enum, patrones |
Cualquier expresión booleana |
Regla práctica: si estás comparando la misma variable contra una lista fija de valores
concretos (categorías, códigos, opciones de menú), usa switch. Si necesitas evaluar rangos,
combinaciones de varias variables, o condiciones más elaboradas, usa if/else if/else
como en la primera lección de este módulo.
- Un vistazo al futuro: switch expressions y pattern matching
El switch clásico que has visto en esta lección existe desde las primeras versiones de C#.
Versiones más recientes del lenguaje incorporan las llamadas switch expressions (una
forma más compacta de escribir un switch que devuelve un valor directamente, sin
case/break) y el pattern matching avanzado (comparar no solo valores exactos, sino
también tipos, rangos o estructuras de datos completas). Como anticipo, así se ve una switch
expression equivalente a uno de los ejemplos anteriores:
string categoria = "Novela";
string seccion = categoria switch
{
"Novela" => "Narrativa - Planta 1",
"Ensayo" => "No ficcion - Planta 2",
"Poesia" => "Poesia - Planta 1",
_ => "Categoria no reconocida"
};
Console.WriteLine(seccion);Por ahora basta con reconocer esta sintaxis si la ves en código ajeno; no es necesario
dominarla todavía. El Módulo 4 (Conceptos Avanzados de C#) dedica una lección completa a
Pattern Matching y Características Modernas, donde profundizarás en las switch expressions,
los patrones de tipo, de propiedad y de rango. Por ahora, domina bien el switch clásico:
es la base sobre la que se entienden todas esas variantes modernas.
- Aplicación completa: clasificar un libro por categoría
Vamos a construir una pequeña utilidad de BiblioTechConsola que, dada la categoría de un libro, determina en qué planta se ubica físicamente y muestra un mensaje descriptivo.
string[] categoriasLibros = { "Novela", "Comic", "Ensayo", "Infantil", "Manga", "Desconocida" };
foreach (string categoria in categoriasLibros)
{
string ubicacion;
switch (categoria)
{
case "Novela":
case "Ciencia Ficcion":
case "Fantasia":
ubicacion = "Planta 1 - Narrativa";
break;
case "Ensayo":
case "Historia":
ubicacion = "Planta 2 - No ficcion";
break;
case "Infantil":
case "Juvenil":
ubicacion = "Planta baja - Seccion familiar";
break;
case "Comic":
case "Manga":
ubicacion = "Planta 1 - Comic y novela grafica";
break;
default:
ubicacion = "Sin ubicacion asignada - revisar con el bibliotecario";
break;
}
Console.WriteLine($"{categoria} -> {ubicacion}");
}Salida esperada:
Novela -> Planta 1 - Narrativa Comic -> Planta 1 - Comic y novela grafica Ensayo -> Planta 2 - No ficcion Infantil -> Planta baja - Seccion familiar Manga -> Planta 1 - Comic y novela grafica Desconocida -> Sin ubicacion asignada - revisar con el bibliotecario
Observa cómo el switch deja el código mucho más ordenado que una larga cadena de else if
comparando siempre la misma variable categoria.
Errores Comunes y Consejos
- Olvidar el
break: en C# no compila uncasecon código que no termine enbreak(u otra instrucción de salida comoreturn). El compilador te avisará con un error claro; no lo interpretes como un capricho del lenguaje, sino como una protección contra el error de fall-through accidental tan común en otros lenguajes. - Duplicar un valor de
case: dos etiquetascasecon el mismo valor no compilan. Revisa que cada valor aparezca una sola vez. - Olvidar el
default: aunque no es obligatorio, omitirlo puede dejar situaciones sin cubrir. En BiblioTechConsola, undefaultbien pensado ("categoría no reconocida") evita comportamientos silenciosos e inesperados. - Usar
switchpara rangos numéricos (paginas > 100 && paginas < 300): elswitchclásico compara igualdad exacta, no rangos; para eso, usaif/else if/else. - Mezclar tipos de valores en los
case: todos los valores de loscasedeben ser compatibles con el tipo de la expresión delswitch(si compara unstring, todos loscasedeben ser cadenas literales).
Ejercicios
-
Declara
int diaSemanacon un valor del 1 al 7. Escribe unswitchque muestre por consola el nombre del día correspondiente (1->"Lunes", ...,7->"Domingo"), y un mensaje"Dia invalido"en eldefault. -
Declara
string formatocon uno de estos valores:"Tapa dura","Tapa blanda","Digital","Audiolibro". Usandocaseapilados, agrupa"Tapa dura"y"Tapa blanda"bajo el mensaje"Formato fisico", y agrupa"Digital"y"Audiolibro"bajo el mensaje"Formato electronico". -
Dado el array
string[] categorias = { "Poesia", "Terror", "Novela" };, recorre el array conforeachy, para cada categoría, usa unswitchpara mostrar"Planta 1"si es"Novela"o"Poesia", y"Sin clasificar"en cualquier otro caso (incluido"Terror", que no está contemplado explícitamente).
Soluciones
int diaSemana = 3;
switch (diaSemana)
{
case 1:
Console.WriteLine("Lunes");
break;
case 2:
Console.WriteLine("Martes");
break;
case 3:
Console.WriteLine("Miercoles");
break;
case 4:
Console.WriteLine("Jueves");
break;
case 5:
Console.WriteLine("Viernes");
break;
case 6:
Console.WriteLine("Sabado");
break;
case 7:
Console.WriteLine("Domingo");
break;
default:
Console.WriteLine("Dia invalido");
break;
}
Con diaSemana = 3, el resultado mostrado es "Miercoles".
string formato = "Digital";
switch (formato)
{
case "Tapa dura":
case "Tapa blanda":
Console.WriteLine("Formato fisico");
break;
case "Digital":
case "Audiolibro":
Console.WriteLine("Formato electronico");
break;
default:
Console.WriteLine("Formato no reconocido");
break;
}
Con formato = "Digital", el resultado mostrado es "Formato electronico".
string[] categorias = { "Poesia", "Terror", "Novela" };
foreach (string categoria in categorias)
{
switch (categoria)
{
case "Novela":
case "Poesia":
Console.WriteLine("Planta 1");
break;
default:
Console.WriteLine("Sin clasificar");
break;
}
}
El resultado mostrado es: "Planta 1" (para "Poesia"), "Sin clasificar" (para
"Terror", que cae en el default al no estar contemplado) y "Planta 1" (para
"Novela").
Conclusión
En esta lección has aprendido a usar switch para comparar una misma variable contra una
lista de valores posibles de forma clara y ordenada, la importancia del break en cada
case, cómo agrupar varios valores bajo una misma acción, y cuándo elegir switch frente a
if/else if/else. También has visto un breve adelanto de las switch expressions y el
pattern matching moderno, que retomarás en profundidad en el Módulo 4.
Hasta ahora, en todos los ejemplos de este módulo, el código ha asumido que los datos llegan
en el formato correcto. Pero en un programa real, cualquier operación —convertir texto a
número, acceder a una posición de un array, prestar un libro que no existe— puede fallar. En
la última lección de este módulo, Manejo de Excepciones, aprenderás a anticipar y
gestionar esos errores de forma controlada con try/catch/finally, para que
BiblioTechConsola no se detenga bruscamente ante un dato inesperado.
Curso de Programación en C#
Módulo 1: Introducción a C#
- Introducción a C#
- Configuración del Entorno de Desarrollo
- Programa Hola Mundo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Arrays y Cadenas de Texto
Módulo 2: Estructuras de Control
Módulo 3: Programación Orientada a Objetos
- Clases y Objetos
- Métodos
- Constructores y Destructores
- Herencia
- Polimorfismo
- Encapsulamiento
- Abstracción
- Structs y Records: Tipos por Valor y por Referencia
Módulo 4: Conceptos Avanzados de C#
- Interfaces
- Delegados y Eventos
- Pattern Matching y Características Modernas de C#
- Genéricos
- Colecciones
- LINQ (Consulta Integrada en el Lenguaje)
- Programación Asíncrona
Módulo 5: Trabajando con Datos
- Entrada/Salida de Archivos
- Serialización
- Conectividad con Bases de Datos
- Entity Framework
- Trabajo con JSON y Consumo de APIs REST
Módulo 6: Temas Avanzados
- Reflexión
- Atributos
- Programación Dinámica
- Gestión de Memoria y Recolección de Basura
- Multihilo y Programación Paralela
Módulo 7: Construcción de Aplicaciones
- Formularios de Windows
- WPF (Windows Presentation Foundation)
- ASP.NET Core
- Blazor
- Xamarin y .NET MAUI
Módulo 8: Mejores Prácticas y Patrones de Diseño
- Estándares de Codificación y Mejores Prácticas
- Patrones de Diseño
- Inyección de Dependencias e Inversión de Control
- Pruebas Unitarias
- Revisión y Refactorización de Código
