Capítulo 6: La sentencia switch en C#
6 min de lectura
Parte I - Sección 2: Lógica de programación - Nivel: Principiante
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
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
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
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
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
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
1. La expresión puede ser: int, string, char, enum, bool (no double ni float)
// Válido
switch (corrienteNominal) // int
switch (tipoCarga) // string
switch (estado) // char
switch (tipoProteccion) // enum
// NO válido
switch (voltaje) // double - ERROR
switch (temperatura) // float - ERROR
2. 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
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
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
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)
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
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
int diaSemana = 3; // 1=Lunes, 7=Domingo
string 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
El bloque default se ejecuta cuando ningún case coincide. Es opcional pero muy recomendable.
6.1 Sin default (peligroso)
string tipo = "X"; // Valor inesperado
string descripcion;
switch (tipo)
{
case "A":
descripcion = "Tipo A";
break;
case "B":
descripcion = "Tipo B";
break;
// Sin default
}
MessageBox.Show(descripcion); // ERROR: 'descripcion' no está asignada
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
int corriente = 35; // Valor no estándar
double 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?
7.1 Usa switch cuando:
Comparas una variable contra valores específicos constantes
// Perfecto para switch
switch (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 switch
switch (numeroPolo)
{
case 1: // ...
case 2: // ...
case 3: // ...
case 4: // ...
}
7.2 Usa if/else if cuando:
Necesitas comparar rangos
// NO puedes hacer esto con switch
if (corriente <= 16.0)
{
seccion = 2.5;
}
else if (corriente <= 25.0)
{
seccion = 6.0;
}
Comparas con double o float
// switch NO funciona con double
double voltaje = 230.5;
if (voltaje >= 207.0 && voltaje <= 253.0)
{
// OK
}
Necesitas condiciones complejas
// Condición compleja - usa if
if (corriente > limite && temperatura < 40 && !alertaActiva)
{
// ...
}
Comparas diferentes variables en cada condición
// Cada condición evalúa variables diferentes - usa if
if (voltaje > 253)
{
// ...
}
else if (corriente > 16)
{
// ...
}
else if (temperatura > 50)
{
// ...
}
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+)
EPLAN 2026 soporta C# moderno, así que puedes usar switch expressions (sintaxis más compacta):
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
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
Vamos a crear un Configurador de Componentes Eléctricos que identifica productos por código.
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
// ========================================
// 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
// ========================================
// 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
// ========================================
// 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
// ========================================
// 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, F1
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
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
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 requisitos
Pero generalmente es mejor usar funciones o lógica clara.
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+)
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
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ódigo
switch (tipo)
{
case "A":
// 20 líneas de código...
break;
case "B":
// 20 líneas de código...
break;
}
// Mejor: delegar a funciones
switch (tipo)
{
case "A":
ProcesarTipoA();
break;
case "B":
ProcesarTipoB();
break;
}
Errores comunes
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
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
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)
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
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
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
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
Preguntas frecuentes
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?
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?
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?
R: Sí, para agrupar casos:
case "A":
case "B":
// Código para ambos
break;
P: ¿El orden de los cases importa?
R: No afecta la funcionalidad, pero ordénalos lógicamente para legibilidad.
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/