Capítulo 6: Control de flujo - switch
Capítulo 6: Control de flujo - switch
Sección titulada «Capítulo 6: Control de flujo - switch»Parte I - Sección 2: Lógica de programación - Nivel: Principiante
Objetivos de aprendizaje
Sección titulada «Objetivos de aprendizaje»Al finalizar este capítulo serás capaz de:
- Usar la estructura switch para comparar una variable contra múltiples valores
- Entender cuándo switch es mejor que múltiples else if
- Manejar casos múltiples con fall-through controlado
- Usar el caso default para valores no esperados
- Construir configuradores de componentes con muchas opciones
Requisitos previos
Sección titulada «Requisitos previos»Antes de comenzar este capítulo debes:
- Haber completado el Capítulo 5
- Entender estructuras if/else if
- Saber comparar valores con ==
- Conocer tipos de datos básicos
Proyecto del capítulo
Sección titulada «Proyecto del capítulo»Configurador de Componentes Eléctricos
Al final de este capítulo habrás construido un script que:
- Identifica componentes por su código de artículo
- Obtiene especificaciones técnicas completas
- Genera descripciones formateadas para documentación
- Maneja decenas de opciones de forma organizada
Contenido
Sección titulada «Contenido»1. Introducción: El problema con muchos else if
Sección titulada «1. Introducción: El problema con muchos else if»En el capítulo anterior vimos este código:
if (tipoCarga == "Motor"){ curva = "D";}else if (tipoCarga == "Iluminacion"){ curva = "B";}else if (tipoCarga == "Tomas"){ curva = "C";}else if (tipoCarga == "Informatica"){ curva = "C";}else{ curva = "C";}Esto funciona, pero con muchas opciones se vuelve repetitivo y difícil de leer.
Problema real: Imagina un configurador que debe identificar 50 tipos diferentes de interruptores por su código de artículo. Con else if tendrías 50 bloques casi idénticos.
Solución: La estructura switch.
2. La estructura switch básica
Sección titulada «2. La estructura switch básica»Sintaxis:
switch (variable){ case valor1: // Código si variable == valor1 break; case valor2: // Código si variable == valor2 break; default: // Código si ningún case coincide break;}Ejemplo práctico - mismo caso anterior:
string tipoCarga = "Motor";string curva;
switch (tipoCarga){ case "Motor": curva = "D"; break; case "Iluminacion": curva = "B"; break; case "Tomas": curva = "C"; break; case "Informatica": curva = "C"; break; default: curva = "C"; break;}Ventajas:
- Más legible cuando hay muchas opciones
- Intención clara: “evaluar variable contra valores”
- Fácil de mantener y extender
3. Anatomía del switch
Sección titulada «3. Anatomía del switch»switch (expresion) ← Variable o expresión a evaluar{ case valorConstante1: ← Valor específico a comparar // Código break; ← OBLIGATORIO: sale del switch
case valorConstante2: // Código break;
default: ← Opcional: caso "ninguno de los anteriores" // Código break;}3.1 Reglas importantes
Sección titulada «3.1 Reglas importantes»1. La expresión puede ser: int, string, char, enum, bool (no double ni float)
// Válidoswitch (corrienteNominal) // intswitch (tipoCarga) // stringswitch (estado) // charswitch (tipoProteccion) // enum
// NO válidoswitch (voltaje) // double - ERRORswitch (temperatura) // float - ERROR2. Cada case debe terminar con break
switch (tipo){ case "A": MessageBox.Show("Tipo A"); break; // OBLIGATORIO case "B": MessageBox.Show("Tipo B"); // Sin break → ERROR de compilación}3. Los valores de case deben ser constantes
const string TIPO_MOTOR = "Motor";int limite = 16;
switch (tipoCarga){ case TIPO_MOTOR: // OK: constante break; case "Iluminacion": // OK: literal break; case limite: // ERROR: no es constante break;}4. Ejemplos prácticos básicos
Sección titulada «4. Ejemplos prácticos básicos»4.1 Switch con int - Seleccionar sección de cable
Sección titulada «4.1 Switch con int - Seleccionar sección de cable»int corrienteNominal = 20;double seccionCable;
switch (corrienteNominal){ case 10: seccionCable = 1.5; break; case 16: seccionCable = 2.5; break; case 20: seccionCable = 4.0; break; case 25: seccionCable = 6.0; break; case 32: seccionCable = 10.0; break; default: seccionCable = 16.0; break;}
MessageBox.Show(string.Format("Corriente: {0}A → Sección: {1}mm²", corrienteNominal, seccionCable));4.2 Switch con string - Tipo de instalación
Sección titulada «4.2 Switch con string - Tipo de instalación»string ambiente = "Humedo";string tipoInstalacion;
switch (ambiente){ case "Seco": tipoInstalacion = "Instalación estándar (B1)"; break; case "Humedo": tipoInstalacion = "Instalación protegida contra agua (B2)"; break; case "Mojado": tipoInstalacion = "Instalación sumergible (B3)"; break; case "Corrosivo": tipoInstalacion = "Instalación con protección química (B4)"; break; default: tipoInstalacion = "No especificado - revisar manualmente"; break;}
MessageBox.Show(tipoInstalacion);4.3 Switch con char - Clase de aislamiento
Sección titulada «4.3 Switch con char - Clase de aislamiento»char claseAislamiento = 'F';int temperaturaMaxima;
switch (claseAislamiento){ case 'Y': temperaturaMaxima = 90; break; case 'A': temperaturaMaxima = 105; break; case 'E': temperaturaMaxima = 120; break; case 'B': temperaturaMaxima = 130; break; case 'F': temperaturaMaxima = 155; break; case 'H': temperaturaMaxima = 180; break; default: temperaturaMaxima = 0; break;}
MessageBox.Show(string.Format("Clase {0}: Temperatura máxima {1}°C", claseAislamiento, temperaturaMaxima));5. Casos múltiples (multiple cases)
Sección titulada «5. Casos múltiples (multiple cases)»Cuando varios valores deben ejecutar el mismo código:
switch (variable){ case valor1: case valor2: case valor3: // Código para valor1, valor2 o valor3 break; case valor4: // Código solo para valor4 break;}5.1 Ejemplo: Clasificar grado de protección IP
Sección titulada «5.1 Ejemplo: Clasificar grado de protección IP»int gradoProteccionIP = 54; // IP54
string descripcion;
switch (gradoProteccionIP){ case 20: case 21: case 22: descripcion = "Protección básica interior"; break; case 44: case 54: case 55: descripcion = "Protección contra polvo y agua (uso industrial)"; break; case 65: case 66: case 67: descripcion = "Protección alta contra agua (uso exterior)"; break; case 68: descripcion = "Protección total (sumergible)"; break; default: descripcion = "Grado IP no reconocido"; break;}
MessageBox.Show(string.Format("IP{0}: {1}", gradoProteccionIP, descripcion));5.2 Ejemplo: Días laborables vs fin de semana
Sección titulada «5.2 Ejemplo: Días laborables vs fin de semana»int diaSemana = 3; // 1=Lunes, 7=Domingostring tipoTarifa;
switch (diaSemana){ case 1: case 2: case 3: case 4: case 5: tipoTarifa = "Tarifa laboral (mayor consumo industrial)"; break; case 6: case 7: tipoTarifa = "Tarifa fin de semana (menor consumo)"; break; default: tipoTarifa = "Día no válido"; break;}
MessageBox.Show(tipoTarifa);6. El caso default
Sección titulada «6. El caso default»El bloque default se ejecuta cuando ningún case coincide. Es opcional pero muy recomendable.
6.1 Sin default (peligroso)
Sección titulada «6.1 Sin default (peligroso)»string tipo = "X"; // Valor inesperadostring descripcion;
switch (tipo){ case "A": descripcion = "Tipo A"; break; case "B": descripcion = "Tipo B"; break; // Sin default}
MessageBox.Show(descripcion); // ERROR: 'descripcion' no está asignada6.2 Con default (seguro)
Sección titulada «6.2 Con default (seguro)»string tipo = "X";string descripcion;
switch (tipo){ case "A": descripcion = "Tipo A"; break; case "B": descripcion = "Tipo B"; break; default: descripcion = "Tipo desconocido"; break;}
MessageBox.Show(descripcion); // "Tipo desconocido"6.3 Default para validación
Sección titulada «6.3 Default para validación»int corriente = 35; // Valor no estándardouble seccion;
switch (corriente){ case 10: seccion = 1.5; break; case 16: seccion = 2.5; break; case 20: seccion = 4.0; break; case 25: seccion = 6.0; break; default: MessageBox.Show("Corriente no estándar. Requiere cálculo manual."); return; // Sale del método}
MessageBox.Show(string.Format("Sección: {0}mm²", seccion));7. Switch vs if/else if - ¿Cuándo usar cada uno?
Sección titulada «7. Switch vs if/else if - ¿Cuándo usar cada uno?»7.1 Usa switch cuando:
Sección titulada «7.1 Usa switch cuando:»Comparas una variable contra valores específicos constantes
// Perfecto para switchswitch (codigoArticulo){ case "3RT2026": descripcion = "Contactor 25A"; break; case "3RT2036": descripcion = "Contactor 40A"; break; // ... más casos}Tienes muchas opciones (>3-4)
Con 10+ opciones, switch es mucho más legible.
Los valores son discretos (no rangos)
// Bien con switchswitch (numeroPolo){ case 1: // ... case 2: // ... case 3: // ... case 4: // ...}7.2 Usa if/else if cuando:
Sección titulada «7.2 Usa if/else if cuando:»Necesitas comparar rangos
// NO puedes hacer esto con switchif (corriente <= 16.0){ seccion = 2.5;}else if (corriente <= 25.0){ seccion = 6.0;}Comparas con double o float
// switch NO funciona con doubledouble voltaje = 230.5;
if (voltaje >= 207.0 && voltaje <= 253.0){ // OK}Necesitas condiciones complejas
// Condición compleja - usa ifif (corriente > limite && temperatura < 40 && !alertaActiva){ // ...}Comparas diferentes variables en cada condición
// Cada condición evalúa variables diferentes - usa ifif (voltaje > 253){ // ...}else if (corriente > 16){ // ...}else if (temperatura > 50){ // ...}7.3 Tabla comparativa
Sección titulada «7.3 Tabla comparativa»| Criterio | switch | if/else if |
|---|---|---|
| Tipo de variable | int, string, char, enum, bool | Cualquier tipo |
| Rangos | No | Sí |
| Valores exactos | Ideal | Funciona |
| Múltiples variables | No | Sí |
| Condiciones complejas | No | Sí |
| Legibilidad (muchas opciones) | Mejor | Se complica |
8. Switch con expresiones (C# 8.0+)
Sección titulada «8. Switch con expresiones (C# 8.0+)»EPLAN 2026 soporta C# moderno, así que puedes usar switch expressions (sintaxis más compacta):
8.1 Sintaxis tradicional vs expression
Sección titulada «8.1 Sintaxis tradicional vs expression»Tradicional:
string tipoCarga = "Motor";string curva;
switch (tipoCarga){ case "Motor": curva = "D"; break; case "Iluminacion": curva = "B"; break; default: curva = "C"; break;}Switch expression (más compacto):
string tipoCarga = "Motor";
string curva = tipoCarga switch{ "Motor" => "D", "Iluminacion" => "B", _ => "C" // _ es el default};8.2 Ejemplo práctico con switch expression
Sección titulada «8.2 Ejemplo práctico con switch expression»int corriente = 20;
double seccion = corriente switch{ 10 => 1.5, 16 => 2.5, 20 => 4.0, 25 => 6.0, 32 => 10.0, _ => 16.0};
MessageBox.Show(string.Format("{0}A → {1}mm²", corriente, seccion));Ventajas:
- Más conciso
- Directamente asigna el resultado
- Menos líneas de código
Cuándo usarlo:
- Asignaciones simples
- No necesitas múltiples líneas de código por caso
- Cuando mejora la legibilidad
Cuándo NO usarlo:
- Cada caso requiere múltiples líneas
- Lógica compleja dentro de cada caso
- Cuando reduce la claridad
Manos a la obra: Construyendo el proyecto
Sección titulada «Manos a la obra: Construyendo el proyecto»Vamos a crear un Configurador de Componentes Eléctricos que identifica productos por código.
Paso 1: Estructura básica
Sección titulada «Paso 1: Estructura básica»using System;using Eplan.EplApi.Base;using Eplan.EplApi.ApplicationFramework;
public class ConfiguradorComponentes{ [Start] public void Ejecutar() { // ======================================== // CÓDIGO DE ARTÍCULO A CONSULTAR // ========================================
string codigoArticulo = "3RT2026-1BB40";
// Variables para almacenar información string tipoComponente; string fabricante; string descripcionCorta; string descripcionLarga; string especificacionesTecnicas; }}Paso 2: Identificar fabricante por prefijo
Sección titulada «Paso 2: Identificar fabricante por prefijo»// ========================================// PASO 1: IDENTIFICAR FABRICANTE// ========================================
string prefijo = codigoArticulo.Substring(0, 3); // Primeros 3 caracteres
switch (prefijo){ case "3RT": case "3RV": case "3RA": case "3RU": fabricante = "Siemens"; break; case "LC1": case "LR2": case "GV2": case "GV3": fabricante = "Schneider Electric"; break; case "AF0": case "AF1": case "AF2": case "AX0": fabricante = "ABB"; break; case "DIL": case "PKZ": case "NZM": fabricante = "Eaton / Moeller"; break; default: fabricante = "Fabricante no identificado"; break;}¿Qué acabamos de hacer? Identificamos el fabricante analizando los primeros 3 caracteres del código de artículo. Diferentes fabricantes usan diferentes prefijos.
Paso 3: Identificar tipo de componente
Sección titulada «Paso 3: Identificar tipo de componente»// ========================================// PASO 2: IDENTIFICAR TIPO DE COMPONENTE// ========================================
switch (prefijo){ case "3RT": case "LC1": case "AF0": case "AF1": case "AF2": case "DIL": tipoComponente = "Contactor"; break; case "3RV": case "PKZ": tipoComponente = "Guardamotor"; break; case "3RA": case "LR2": case "AX0": tipoComponente = "Relé térmico"; break; case "3RU": tipoComponente = "Relé de sobrecarga"; break; case "GV2": case "GV3": tipoComponente = "Disyuntor motor"; break; case "NZM": tipoComponente = "Interruptor automático caja moldeada"; break; default: tipoComponente = "Componente no identificado"; break;}Paso 4: Obtener especificaciones según código completo
Sección titulada «Paso 4: Obtener especificaciones según código completo»// ========================================// PASO 3: ESPECIFICACIONES POR CÓDIGO// ========================================
switch (codigoArticulo){ // Contactores Siemens 3RT20 case "3RT2026-1BB40": descripcionCorta = "Contactor 3P 25A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 25A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 25A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 18.5kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
case "3RT2036-1BB40": descripcionCorta = "Contactor 3P 40A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 40A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 40A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 22kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
case "3RT2046-1BB40": descripcionCorta = "Contactor 3P 65A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 65A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 65A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 37kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
// Guardamotores Siemens 3RV20 case "3RV2011-1JA10": descripcionCorta = "Guardamotor 3.5-5A"; descripcionLarga = "Guardamotor ajustable, rango 3.5-5A, " + "disparo magnético 65A"; especificacionesTecnicas = "- Rango ajuste: 3.5-5A\n" + "- Disparo magnético: 65A\n" + "- Poder de corte: 100kA @ 400V\n" + "- Clase disparo: Clase 10\n" + "- Contactos auxiliares: 1NA+1NC"; break;
case "3RV2021-4BA10": descripcionCorta = "Guardamotor 18-25A"; descripcionLarga = "Guardamotor ajustable, rango 18-25A, " + "disparo magnético 325A"; especificacionesTecnicas = "- Rango ajuste: 18-25A\n" + "- Disparo magnético: 325A\n" + "- Poder de corte: 100kA @ 400V\n" + "- Clase disparo: Clase 10\n" + "- Contactos auxiliares: 1NA+1NC"; break;
// Contactores Schneider LC1D case "LC1D09BD": descripcionCorta = "Contactor 3P 9A AC3"; descripcionLarga = "Contactor TeSys D, corriente nominal 9A en AC3, " + "bobina 24V DC"; especificacionesTecnicas = "- Corriente nominal: 9A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 4kW @ 400V\n" + "- Serie: TeSys D"; break;
case "LC1D18BD": descripcionCorta = "Contactor 3P 18A AC3"; descripcionLarga = "Contactor TeSys D, corriente nominal 18A en AC3, " + "bobina 24V DC"; especificacionesTecnicas = "- Corriente nominal: 18A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 7.5kW @ 400V\n" + "- Serie: TeSys D"; break;
// Contactores ABB case "AF09-30-10-13": descripcionCorta = "Contactor 3P 9A AC3"; descripcionLarga = "Contactor AF, corriente nominal 9A en AC3, " + "bobina 100-250V AC/DC"; especificacionesTecnicas = "- Corriente nominal: 9A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 100-250V AC/DC\n" + "- Contactos auxiliares: 1NA\n" + "- Poder de corte: 4kW @ 400V\n" + "- Serie: AF"; break;
// Caso default default: descripcionCorta = "Código no encontrado en base de datos"; descripcionLarga = string.Format( "El código '{0}' no está registrado en el configurador. " + "Consulte catálogo del fabricante.", codigoArticulo ); especificacionesTecnicas = "No disponible"; break;}¿Qué acabamos de hacer? Creamos una base de datos de componentes usando switch. Cada código de artículo tiene sus especificaciones completas.
Paso 5: Generar código de designación EPLAN
Sección titulada «Paso 5: Generar código de designación EPLAN»// ========================================// PASO 4: GENERAR DESIGNACIÓN EPLAN// ========================================
string prefijoDesignacion;
switch (tipoComponente){ case "Contactor": prefijoDesignacion = "K"; break; case "Guardamotor": prefijoDesignacion = "Q"; break; case "Relé térmico": case "Relé de sobrecarga": prefijoDesignacion = "F"; break; case "Disyuntor motor": prefijoDesignacion = "Q"; break; case "Interruptor automático caja moldeada": prefijoDesignacion = "Q"; break; default: prefijoDesignacion = "?"; break;}
string designacionSugerida = prefijoDesignacion + "1"; // Ejemplo: K1, Q1, F1Paso 6: Construir reporte final
Sección titulada «Paso 6: Construir reporte final»// ========================================// CONSTRUCCIÓN DEL REPORTE// ========================================
string separador = new string('=', 50);
string reporte = string.Format( "{0}\n" + "CONFIGURADOR DE COMPONENTES ELÉCTRICOS\n" + "{0}\n\n" + "CÓDIGO DE ARTÍCULO: {1}\n\n" + "IDENTIFICACIÓN:\n" + "- Fabricante: {2}\n" + "- Tipo: {3}\n" + "- Designación sugerida: {4}\n\n" + "DESCRIPCIÓN:\n" + "{5}\n\n" + "ESPECIFICACIONES TÉCNICAS:\n" + "{6}\n\n" + "{0}", separador, codigoArticulo, fabricante, tipoComponente, designacionSugerida, descripcionLarga, especificacionesTecnicas);
// ========================================// MOSTRAR REPORTE// ========================================
MessageBoxIcon icono = (fabricante == "Fabricante no identificado") ? MessageBoxIcon.Warning : MessageBoxIcon.Information;
MessageBox.Show(reporte, "Configurador de Componentes", MessageBoxButtons.OK, icono);Código completo del proyecto
Sección titulada «Código completo del proyecto»using System;using Eplan.EplApi.Base;using Eplan.EplApi.ApplicationFramework;
public class ConfiguradorComponentes{ [Start] public void Ejecutar() { // ======================================== // CÓDIGO DE ARTÍCULO A CONSULTAR // ========================================
string codigoArticulo = "3RT2026-1BB40";
// Variables para almacenar información string tipoComponente; string fabricante; string descripcionCorta; string descripcionLarga; string especificacionesTecnicas;
// ======================================== // PASO 1: IDENTIFICAR FABRICANTE // ========================================
string prefijo = codigoArticulo.Substring(0, 3);
switch (prefijo) { case "3RT": case "3RV": case "3RA": case "3RU": fabricante = "Siemens"; break; case "LC1": case "LR2": case "GV2": case "GV3": fabricante = "Schneider Electric"; break; case "AF0": case "AF1": case "AF2": case "AX0": fabricante = "ABB"; break; case "DIL": case "PKZ": case "NZM": fabricante = "Eaton / Moeller"; break; default: fabricante = "Fabricante no identificado"; break; }
// ======================================== // PASO 2: IDENTIFICAR TIPO DE COMPONENTE // ========================================
switch (prefijo) { case "3RT": case "LC1": case "AF0": case "AF1": case "AF2": case "DIL": tipoComponente = "Contactor"; break; case "3RV": case "PKZ": tipoComponente = "Guardamotor"; break; case "3RA": case "LR2": case "AX0": tipoComponente = "Relé térmico"; break; case "3RU": tipoComponente = "Relé de sobrecarga"; break; case "GV2": case "GV3": tipoComponente = "Disyuntor motor"; break; case "NZM": tipoComponente = "Interruptor automático caja moldeada"; break; default: tipoComponente = "Componente no identificado"; break; }
// ======================================== // PASO 3: ESPECIFICACIONES POR CÓDIGO // ========================================
switch (codigoArticulo) { // Contactores Siemens 3RT20 case "3RT2026-1BB40": descripcionCorta = "Contactor 3P 25A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 25A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 25A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 18.5kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
case "3RT2036-1BB40": descripcionCorta = "Contactor 3P 40A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 40A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 40A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 22kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
case "3RT2046-1BB40": descripcionCorta = "Contactor 3P 65A AC3"; descripcionLarga = "Contactor tripolar, corriente nominal 65A en AC3, " + "bobina 24V DC, 1NA+1NC auxiliar"; especificacionesTecnicas = "- Corriente nominal: 65A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 37kW @ 400V\n" + "- Categoría: AC3 (motores)"; break;
// Guardamotores Siemens 3RV20 case "3RV2011-1JA10": descripcionCorta = "Guardamotor 3.5-5A"; descripcionLarga = "Guardamotor ajustable, rango 3.5-5A, " + "disparo magnético 65A"; especificacionesTecnicas = "- Rango ajuste: 3.5-5A\n" + "- Disparo magnético: 65A\n" + "- Poder de corte: 100kA @ 400V\n" + "- Clase disparo: Clase 10\n" + "- Contactos auxiliares: 1NA+1NC"; break;
case "3RV2021-4BA10": descripcionCorta = "Guardamotor 18-25A"; descripcionLarga = "Guardamotor ajustable, rango 18-25A, " + "disparo magnético 325A"; especificacionesTecnicas = "- Rango ajuste: 18-25A\n" + "- Disparo magnético: 325A\n" + "- Poder de corte: 100kA @ 400V\n" + "- Clase disparo: Clase 10\n" + "- Contactos auxiliares: 1NA+1NC"; break;
// Contactores Schneider LC1D case "LC1D09BD": descripcionCorta = "Contactor 3P 9A AC3"; descripcionLarga = "Contactor TeSys D, corriente nominal 9A en AC3, " + "bobina 24V DC"; especificacionesTecnicas = "- Corriente nominal: 9A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 4kW @ 400V\n" + "- Serie: TeSys D"; break;
case "LC1D18BD": descripcionCorta = "Contactor 3P 18A AC3"; descripcionLarga = "Contactor TeSys D, corriente nominal 18A en AC3, " + "bobina 24V DC"; especificacionesTecnicas = "- Corriente nominal: 18A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 24V DC\n" + "- Contactos auxiliares: 1NA + 1NC\n" + "- Poder de corte: 7.5kW @ 400V\n" + "- Serie: TeSys D"; break;
// Contactores ABB case "AF09-30-10-13": descripcionCorta = "Contactor 3P 9A AC3"; descripcionLarga = "Contactor AF, corriente nominal 9A en AC3, " + "bobina 100-250V AC/DC"; especificacionesTecnicas = "- Corriente nominal: 9A (AC3)\n" + "- Polos principales: 3\n" + "- Bobina: 100-250V AC/DC\n" + "- Contactos auxiliares: 1NA\n" + "- Poder de corte: 4kW @ 400V\n" + "- Serie: AF"; break;
// Caso default default: descripcionCorta = "Código no encontrado en base de datos"; descripcionLarga = string.Format( "El código '{0}' no está registrado en el configurador. " + "Consulte catálogo del fabricante.", codigoArticulo ); especificacionesTecnicas = "No disponible"; break; }
// ======================================== // PASO 4: GENERAR DESIGNACIÓN EPLAN // ========================================
string prefijoDesignacion;
switch (tipoComponente) { case "Contactor": prefijoDesignacion = "K"; break; case "Guardamotor": prefijoDesignacion = "Q"; break; case "Relé térmico": case "Relé de sobrecarga": prefijoDesignacion = "F"; break; case "Disyuntor motor": prefijoDesignacion = "Q"; break; case "Interruptor automático caja moldeada": prefijoDesignacion = "Q"; break; default: prefijoDesignacion = "?"; break; }
string designacionSugerida = prefijoDesignacion + "1";
// ======================================== // CONSTRUCCIÓN DEL REPORTE // ========================================
string separador = new string('=', 50);
string reporte = string.Format( "{0}\n" + "CONFIGURADOR DE COMPONENTES ELÉCTRICOS\n" + "{0}\n\n" + "CÓDIGO DE ARTÍCULO: {1}\n\n" + "IDENTIFICACIÓN:\n" + "- Fabricante: {2}\n" + "- Tipo: {3}\n" + "- Designación sugerida: {4}\n\n" + "DESCRIPCIÓN:\n" + "{5}\n\n" + "ESPECIFICACIONES TÉCNICAS:\n" + "{6}\n\n" + "{0}", separador, codigoArticulo, fabricante, tipoComponente, designacionSugerida, descripcionLarga, especificacionesTecnicas );
// ======================================== // MOSTRAR REPORTE // ========================================
MessageBoxIcon icono = (fabricante == "Fabricante no identificado") ? MessageBoxIcon.Warning : MessageBoxIcon.Information;
MessageBox.Show(reporte, "Configurador de Componentes", MessageBoxButtons.OK, icono); }}Ejercicios:
- Cambia
codigoArticuloa “3RV2011-1JA10” (guardamotor) - Prueba con “LC1D18BD” (Schneider)
- Prueba con “XXXX” (código no existente)
- Agrega más componentes al switch
Deep Dive: Entendiendo en profundidad
Sección titulada «Deep Dive: Entendiendo en profundidad»Fall-through y goto case
Sección titulada «Fall-through y goto case»En algunos lenguajes, si olvidas break, el código “cae” al siguiente caso (fall-through). En C#, esto es error de compilación para evitar bugs.
Pero puedes hacerlo explícitamente con goto case:
switch (codigo){ case "A": MessageBox.Show("Procesando A"); goto case "B"; // Continúa explícitamente en B case "B": MessageBox.Show("Procesando B"); break;}Uso práctico (raro):
string tipoInstalacion = "Industrial";string requisitosSeguirdad = "";
switch (tipoInstalacion){ case "Industrial": requisitosSeguirdad += "- Señalización de emergencia\n"; goto case "Comercial"; case "Comercial": requisitosSeguirdad += "- Iluminación de emergencia\n"; goto case "Residencial"; case "Residencial": requisitosSeguirdad += "- Protección diferencial 30mA\n"; break;}// Industrial tiene los 3 requisitosPero generalmente es mejor usar funciones o lógica clara.
Enums con switch
Sección titulada «Enums con switch»Los enum (enumeraciones) funcionan perfectamente con switch:
enum TipoProteccion{ TipoB, TipoC, TipoD}
TipoProteccion tipo = TipoProteccion.TipoD;
switch (tipo){ case TipoProteccion.TipoB: MessageBox.Show("Para iluminación"); break; case TipoProteccion.TipoC: MessageBox.Show("Para uso general"); break; case TipoProteccion.TipoD: MessageBox.Show("Para motores"); break;}Lo veremos en detalle en capítulos posteriores.
Pattern matching (C# 7.0+)
Sección titulada «Pattern matching (C# 7.0+)»Switch moderno permite patrones más complejos:
object obj = 25;
switch (obj){ case int i when i < 16: MessageBox.Show("Entero menor a 16"); break; case int i when i >= 16: MessageBox.Show("Entero mayor o igual a 16"); break; case string s: MessageBox.Show("Es un string"); break; default: MessageBox.Show("Otro tipo"); break;}Mejores prácticas
Sección titulada «Mejores prácticas»1. Siempre incluye default
Aunque creas que cubriste todos los casos, siempre incluye default para casos inesperados.
2. Ordena los casos lógicamente
// Bien: orden lógico (de menor a mayor)switch (corriente){ case 10: // ... case 16: // ... case 20: // ... case 25: // ...}3. Usa constantes para valores repetidos
const string TIPO_MOTOR = "Motor";const string TIPO_ILUMINACION = "Iluminacion";
switch (tipoCarga){ case TIPO_MOTOR: // ... case TIPO_ILUMINACION: // ...}4. No abuses del switch para lógica compleja
Si cada caso tiene 20 líneas de código, considera usar funciones:
// Mal: casos con mucho códigoswitch (tipo){ case "A": // 20 líneas de código... break; case "B": // 20 líneas de código... break;}
// Mejor: delegar a funcionesswitch (tipo){ case "A": ProcesarTipoA(); break; case "B": ProcesarTipoB(); break;}Errores comunes
Sección titulada «Errores comunes»Error 1: Olvidar break
Sección titulada «Error 1: Olvidar break»switch (tipo){ case "A": MessageBox.Show("A"); // Sin break - ERROR de compilación case "B": MessageBox.Show("B"); break;}Solución: Siempre pon break, return, goto o throw.
Error 2: Usar variables no constantes en case
Sección titulada «Error 2: Usar variables no constantes en case»int limite = 16;
switch (corriente){ case limite: // ERROR: debe ser constante break;}Solución: Usa const o literal:
const int LIMITE = 16;
switch (corriente){ case LIMITE: // OK break;}Error 3: Usar tipos no soportados
Sección titulada «Error 3: Usar tipos no soportados»double voltaje = 230.5;
switch (voltaje) // ERROR: double no soportado{ case 230.0: break;}Solución: Usa if/else if para double/float.
Desafíos (Opcional)
Sección titulada «Desafíos (Opcional)»Desafío 1: Convertidor de grados de protección IP a texto
Sección titulada «Desafío 1: Convertidor de grados de protección IP a texto»Dificultad: Bajo
Crea un script que convierta códigos IP (20, 44, 54, 65, 67, 68) a descripciones completas incluyendo:
- Protección contra sólidos
- Protección contra líquidos
- Aplicaciones típicas
Pista
Usa switch con el código IP completo y asigna descripciones detalladas a cada caso.
Desafío 2: Decodificador de designaciones IEC
Sección titulada «Desafío 2: Decodificador de designaciones IEC»Dificultad: Medio
Crea un script que identifique el tipo de componente por su letra de designación IEC:
- K = Contactor, relé
- Q = Interruptor, seccionador
- F = Protección
- M = Motor
- T = Transformador
- etc.
Y genere una descripción del propósito típico.
Desafío 3: Configurador de curvas de magnetotérmicos extendido
Sección titulada «Desafío 3: Configurador de curvas de magnetotérmicos extendido»Dificultad: Alta
Crea un script completo que:
- Reciba: tipo de carga, corriente nominal, voltaje, número de polos
- Determine: curva de disparo (B/C/D/K/Z), corriente nominal, número de polos
- Genere: código de artículo automático en formato estándar
- Calcule: poder de corte necesario según instalación
Resumen
Sección titulada «Resumen»En este capítulo aprendiste:
- Estructura switch: Comparar una variable contra múltiples valores constantes
- Casos múltiples: Varios case ejecutando el mismo código
- Caso default: Manejar valores no esperados
- Cuándo usar switch vs if/else: Criterios de decisión
- Switch expressions: Sintaxis moderna más compacta (C# 8.0+)
- Proyecto construido: Configurador de componentes eléctricos con base de datos
Conceptos clave:
- Switch es ideal para comparar una variable contra muchos valores específicos
- Cada case debe terminar con break (o return/goto/throw)
- El default es opcional pero muy recomendable
- Solo funciona con int, string, char, enum, bool (no double/float)
- Para rangos o condiciones complejas, usa if/else if
Recursos adicionales
Sección titulada «Recursos adicionales»Preguntas frecuentes
Sección titulada «Preguntas frecuentes»P: ¿Puedo usar switch con double o float?
Sección titulada «P: ¿Puedo usar switch con double o float?»R: No. Switch solo funciona con int, string, char, enum, bool. Para double/float usa if/else if.
P: ¿Qué pasa si olvido el break?
Sección titulada «P: ¿Qué pasa si olvido el break?»R: Error de compilación. C# obliga a terminar cada case con break, return, goto o throw.
P: ¿Cuándo usar switch expression vs switch tradicional?
Sección titulada «P: ¿Cuándo usar switch expression vs switch tradicional?»R: Usa switch expression para asignaciones simples de una línea. Usa switch tradicional cuando cada caso necesita múltiples líneas de código.
P: ¿Puedo tener un case vacío?
Sección titulada «P: ¿Puedo tener un case vacío?»R: Sí, para agrupar casos:
case "A":case "B": // Código para ambos break;P: ¿El orden de los cases importa?
Sección titulada «P: ¿El orden de los cases importa?»R: No afecta la funcionalidad, pero ordénalos lógicamente para legibilidad.
Checklist de completitud
Sección titulada «Checklist de completitud»Antes de pasar al siguiente capítulo, asegúrate de:
- Entender la sintaxis básica de switch
- Saber cuándo usar switch vs if/else if
- Poder agrupar múltiples cases
- Siempre incluir break en cada case
- Usar default para casos no previstos
- Conocer las limitaciones de switch (tipos soportados)
- Haber ejecutado exitosamente el configurador de componentes
- Poder agregar nuevos componentes al switch
- (Opcional) Conocer switch expressions
- (Opcional) Haber intentado al menos un desafío
Última actualización: Enero 2025
Tiempo de lectura estimado: 40-50 minutos
Código de ejemplo: code/cap-06/