Ir al contenido

Capítulo 6: Control de flujo - switch

Parte I - Sección 2: Lógica de programación - Nivel: Principiante


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

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

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

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.


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

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;
}

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.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);
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));

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=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);

El bloque default se ejecuta cuando ningún case coincide. Es opcional pero muy recomendable.

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
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"
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?

Sección titulada «7. Switch vs if/else if - ¿Cuándo usar cada uno?»

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: // ...
}

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)
{
// ...
}
Criterioswitchif/else if
Tipo de variableint, string, char, enum, boolCualquier tipo
RangosNo
Valores exactosIdealFunciona
Múltiples variablesNo
Condiciones complejasNo
Legibilidad (muchas opciones)MejorSe complica

EPLAN 2026 soporta C# moderno, así que puedes usar switch expressions (sintaxis más compacta):

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
};
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

Vamos a crear un Configurador de Componentes Eléctricos que identifica productos por código.

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); // 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 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, F1

// ========================================
// 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);

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 codigoArticulo a “3RV2011-1JA10” (guardamotor)
  • Prueba con “LC1D18BD” (Schneider)
  • Prueba con “XXXX” (código no existente)
  • Agrega más componentes al switch

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.

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.

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;
}

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;
}
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;
}

double voltaje = 230.5;
switch (voltaje) // ERROR: double no soportado
{
case 230.0:
break;
}

Solución: Usa if/else if para double/float.


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:

  1. Reciba: tipo de carga, corriente nominal, voltaje, número de polos
  2. Determine: curva de disparo (B/C/D/K/Z), corriente nominal, número de polos
  3. Genere: código de artículo automático en formato estándar
  4. Calcule: poder de corte necesario según instalación

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


R: No. Switch solo funciona con int, string, char, enum, bool. Para double/float usa if/else if.

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.

R: Sí, para agrupar casos:

case "A":
case "B":
// Código para ambos
break;

R: No afecta la funcionalidad, pero ordénalos lógicamente para legibilidad.


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/