Capítulo 8: Funciones y métodos en C#

6 min de lectura

Parte I - Sección 2: Programación desde cero - Nivel: Principiante


Objetivos de aprendizaje

Al finalizar este capítulo serás capaz de:

  • Entender qué es una función y por qué son fundamentales
  • Crear funciones con parámetros y valores de retorno
  • Diferenciar void de funciones que devuelven valores
  • Comprender scope de variables (local vs global)
  • Sobrecargar funciones con diferentes firmas
  • Usar parámetros opcionales para mayor flexibilidad
  • Construir una librería de funciones reutilizables para ingeniería eléctrica

Requisitos previos

Antes de comenzar este capítulo debes:

  • Haber completado el Capítulo 7
  • Entender bucles (for, foreach, while)
  • Conocer variables y tipos de datos
  • Saber usar operadores y expresiones

Proyecto del capítulo

Librería de Funciones para Cálculos Eléctricos

Al final de este capítulo habrás construido una librería completa con funciones para:

  • Ley de Ohm (V, I, R, P)
  • Caída de tensión en cables
  • Potencia trifásica
  • Conversión de unidades
  • Dimensionado de cables

Tiempo estimado: 55-65 minutos


Contenido

1. Introducción: El problema del código duplicado

Imagina que necesitas calcular la Ley de Ohm en 10 lugares diferentes de tu código:

Sin funciones (código duplicado):

// Lugar 1
double voltaje1 = 230.0;
double corriente1 = 10.0;
double resistencia1 = voltaje1 / corriente1;

// Lugar 2
double voltaje2 = 400.0;
double corriente2 = 16.0;
double resistencia2 = voltaje2 / corriente2;

// Lugar 3... Lugar 4... Lugar 5...
// Repetir la misma fórmula 10 veces

Problemas:

  • Si la fórmula tiene un error, debes corregirla en 10 lugares
  • Si cambias la lógica, debes actualizar 10 lugares
  • Código difícil de mantener

Con funciones (código reutilizable):

// Definir una vez
double CalcularResistencia(double voltaje, double corriente)
{
    return voltaje / corriente;
}

// Usar muchas veces
double resistencia1 = CalcularResistencia(230, 10);
double resistencia2 = CalcularResistencia(400, 16);
double resistencia3 = CalcularResistencia(230, 25);
// ...

Ventajas:

  • Código más limpio y legible
  • Fácil de mantener (cambias en un solo lugar)
  • Reutilizable en cualquier parte del código
  • Reduce errores

Las funciones son el pilar de la programación profesional.


2. ¿Qué es una función?

Una función es un bloque de código con nombre que:

  1. Realiza una tarea específica
  2. Puede recibir datos de entrada (parámetros)
  3. Puede devolver un resultado
  4. Se puede llamar/invocar múltiples veces

Analogía: Piensa en una función como una máquina:

  • Entrada: Materias primas (parámetros)
  • Proceso: Transformación (código de la función)
  • Salida: Producto terminado (valor de retorno)

Ejemplo real: Una calculadora es una función

Entrada: 5, 3, operación "+"
Proceso: Sumar 5 + 3
Salida: 8

3. Sintaxis básica de una función

tipoRetorno NombreFuncion(parametro1, parametro2, ...)
{
    // Código de la función
    return valor;  // Si devuelve algo
}

Componentes:

  • tipoRetorno: Tipo de dato que devuelve (double, int, string, void)
  • NombreFuncion: Nombre descriptivo (PascalCase por convención)
  • parámetros: Datos de entrada (tipo nombre)
  • return: Devuelve el resultado (opcional si es void)

4. Funciones que devuelven valores

4.1 Función simple sin parámetros

double ObtenerVoltajeNominal()
{
    return 230.0;
}

// Uso
double voltaje = ObtenerVoltajeNominal();
MessageBox.Show("Voltaje: " + voltaje + "V");
// Voltaje: 230V

4.2 Función con un parámetro

double CalcularPotencia(double corriente)
{
    double voltaje = 230.0;
    double potencia = voltaje * corriente;
    return potencia;
}

// Uso
double potencia = CalcularPotencia(16.0);
MessageBox.Show("Potencia: " + potencia + "W");
// Potencia: 3680W

4.3 Función con múltiples parámetros

double CalcularResistencia(double voltaje, double corriente)
{
    return voltaje / corriente;
}

// Uso
double resistencia = CalcularResistencia(230.0, 10.0);
MessageBox.Show("Resistencia: " + resistencia + " Ω");
// Resistencia: 23 Ω

4.4 Ejemplos prácticos

Ejemplo 1: Ley de Ohm - Calcular voltaje

double CalcularVoltaje(double corriente, double resistencia)
{
    // V = I × R
    return corriente * resistencia;
}

// Uso
double voltaje = CalcularVoltaje(10.0, 23.0);
MessageBox.Show(string.Format("Voltaje: {0:F2}V", voltaje));
// Voltaje: 230.00V

Ejemplo 2: Calcular caída de tensión

double CalcularCaidaTension(double longitud, double corriente, double seccion)
{
    // ΔV = 2 × L × I × ρ / S
    // ρ (resistividad cobre) = 0.018 Ω·mm²/m
    double resistividad = 0.018;
    return (2 * longitud * corriente * resistividad) / seccion;
}

// Uso
double caida = CalcularCaidaTension(50.0, 16.0, 2.5);
MessageBox.Show(string.Format("Caída de tensión: {0:F2}V", caida));
// Caída de tensión: 11.52V

Ejemplo 3: Convertir kW a HP

double ConvertirKWaHP(double potenciaKW)
{
    // 1 kW = 1.341 HP
    return potenciaKW * 1.341;
}

// Uso
double potenciaKW = 7.5;
double potenciaHP = ConvertirKWaHP(potenciaKW);
MessageBox.Show(string.Format("{0}kW = {1:F2}HP", potenciaKW, potenciaHP));
// 7.5kW = 10.06HP

5. Funciones void - Sin valor de retorno

Funciones void no devuelven ningún valor. Se usan para realizar acciones.

5.1 Sintaxis

void NombreFuncion(parametros)
{
    // Código que realiza una acción
    // NO usa return (o return sin valor)
}

5.2 Ejemplos prácticos

Ejemplo 1: Mostrar mensaje formateado

void MostrarResumen(string componente, double corriente, double potencia)
{
    string mensaje = string.Format(
        "Componente: {0}\n" +
        "Corriente: {1:F1}A\n" +
        "Potencia: {2:F2}W",
        componente,
        corriente,
        potencia
    );

    MessageBox.Show(mensaje, "Resumen", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

// Uso
MostrarResumen("Motor M1", 18.5, 4255.0);

Ejemplo 2: Validar y alertar

void ValidarVoltaje(double voltaje)
{
    double minimo = 207.0;
    double maximo = 253.0;

    if (voltaje < minimo || voltaje > maximo)
    {
        MessageBox.Show(
            string.Format("ADVERTENCIA: Voltaje {0:F1}V fuera de rango ({1}V - {2}V)",
                voltaje, minimo, maximo),
            "Voltaje Anormal",
            MessageBoxButtons.OK,
            MessageBoxIcon.Warning
        );
    }
    else
    {
        MessageBox.Show(
            string.Format("Voltaje {0:F1}V - Normal", voltaje),
            "Voltaje OK",
            MessageBoxButtons.OK,
            MessageBoxIcon.Information
        );
    }
}

// Uso
ValidarVoltaje(195.0);  // Muestra advertencia
ValidarVoltaje(230.0);  // Muestra OK

Ejemplo 3: Imprimir tabla

void ImprimirTablaCaidas(double seccion)
{
    string tabla = string.Format("Caídas de tensión para cable {0}mm²\n", seccion);
    tabla += "====================================\n";
    tabla += "Longitud | Corriente | Caída\n";
    tabla += "------------------------------------\n";

    double[] longitudes = {10, 25, 50, 75, 100};
    double corriente = 16.0;

    foreach (double longitud in longitudes)
    {
        double caida = CalcularCaidaTension(longitud, corriente, seccion);
        tabla += string.Format("{0,8}m | {1,9}A | {2,5:F2}V\n", longitud, corriente, caida);
    }

    MessageBox.Show(tabla, "Tabla de Caídas");
}

// Uso
ImprimirTablaCaidas(2.5);

5.3 ¿Cuándo usar void?

Usa funciones con return cuando:

  • Necesitas calcular y devolver un valor
  • El resultado se usará en otras operaciones
  • Ejemplo: CalcularResistencia(), ConvertirUnidades()

Usa void cuando:

  • Solo realizas una acción (mostrar, imprimir, validar)
  • No necesitas devolver ningún resultado
  • Ejemplo: MostrarMensaje(), ValidarDatos(), ImprimirReporte()

6. Parámetros de funciones

6.1 Parámetros por valor (por defecto)

Los parámetros se copian. Cambios dentro de la función NO afectan el original.

void ModificarValor(int numero)
{
    numero = 100;  // Modifica la copia, no el original
    MessageBox.Show("Dentro de función: " + numero);
}

// Uso
int valor = 10;
ModificarValor(valor);
MessageBox.Show("Fuera de función: " + valor);
// Dentro de función: 100
// Fuera de función: 10 (¡no cambió!)

6.2 Múltiples parámetros de diferentes tipos

string GenerarEtiqueta(string designacion, double corriente, bool esTrifasico, int numeroPolo)
{
    string tipo = esTrifasico ? "3~" : "1~";
    return string.Format("{0} | {1}A | {2} | {3}P", designacion, corriente, tipo, numeroPolo);
}

// Uso
string etiqueta = GenerarEtiqueta("Q1", 25.0, true, 3);
MessageBox.Show(etiqueta);
// Q1 | 25A | 3~ | 3P

6.3 Parámetros con valores predeterminados (opcionales)

double CalcularPotenciaTrifasica(double voltaje, double corriente, double factorPotencia = 1.0)
{
    // P = √3 × V × I × cos φ
    return Math.Sqrt(3) * voltaje * corriente * factorPotencia;
}

// Uso sin especificar factor de potencia (usa 1.0 por defecto)
double p1 = CalcularPotenciaTrifasica(400.0, 50.0);
MessageBox.Show("Potencia 1: " + p1);
// Potencia 1: 34641

// Uso especificando factor de potencia
double p2 = CalcularPotenciaTrifasica(400.0, 50.0, 0.85);
MessageBox.Show("Potencia 2: " + p2);
// Potencia 2: 29445

Reglas de parámetros opcionales:

  • Deben estar al final de la lista de parámetros
  • Se especifica valor predeterminado con =
// Correcto
double Funcion(double a, double b, double c = 10.0, string d = "default")

// Error: parámetros opcionales deben estar al final
double Funcion(double a, double b = 10.0, double c, string d)  //  ERROR

7. Scope de variables (ámbito)

El scope determina dónde una variable es visible y accesible.

7.1 Variables locales (dentro de función)

Variables declaradas dentro de una función solo existen en esa función.

double CalcularPotencia(double voltaje, double corriente)
{
    // 'resultado' es una variable LOCAL
    double resultado = voltaje * corriente;
    return resultado;
}

// Uso
double potencia = CalcularPotencia(230, 10);
MessageBox.Show("Potencia: " + potencia);
// MessageBox.Show("Resultado: " + resultado);  //  ERROR: 'resultado' no existe aquí

7.2 Variables globales (nivel de clase)

Variables declaradas fuera de funciones (a nivel de clase) son accesibles desde todas las funciones.

public class CalculadoraElectrica
{
    // Variables globales (campos de la clase)
    private const double VOLTAJE_NOMINAL = 230.0;
    private const double RESISTIVIDAD_COBRE = 0.018;

    [Start]
    public void Ejecutar()
    {
        double p1 = CalcularPotencia(10.0);
        double p2 = CalcularPotencia(16.0);
        // Ambas funciones usan VOLTAJE_NOMINAL
    }

    double CalcularPotencia(double corriente)
    {
        // Puede acceder a VOLTAJE_NOMINAL porque es global
        return VOLTAJE_NOMINAL * corriente;
    }

    double CalcularCaidaTension(double longitud, double corriente, double seccion)
    {
        // Puede acceder a RESISTIVIDAD_COBRE porque es global
        return (2 * longitud * corriente * RESISTIVIDAD_COBRE) / seccion;
    }
}

7.3 Buenas prácticas de scope

Prefiere variables locales:

// Bien: variables locales
double CalcularPotencia(double voltaje, double corriente)
{
    double resultado = voltaje * corriente;  // Local, no contamina otros métodos
    return resultado;
}

Usa constantes globales para valores fijos:

// Bien: constantes globales para valores que no cambian
private const double VOLTAJE_NOMINAL_EU = 230.0;
private const double VOLTAJE_NOMINAL_US = 120.0;
private const double FRECUENCIA_EU = 50.0;
private const double FRECUENCIA_US = 60.0;

Evita variables globales mutables:

// Mal: variable global que cambia
private double voltajeActual = 230.0;  // ¿Quién la modifica? ¿Cuándo?

// Mejor: pasar como parámetro
double CalcularPotencia(double voltaje, double corriente)
{
    return voltaje * corriente;
}

8. Sobrecarga de funciones (Overloading)

La sobrecarga permite tener múltiples funciones con el mismo nombre pero diferentes parámetros.

8.1 Sintaxis

// Misma función, diferentes firmas
double CalcularPotencia(double corriente)  // 1 parámetro
double CalcularPotencia(double voltaje, double corriente)  // 2 parámetros
double CalcularPotencia(double voltaje, double corriente, double factorPotencia)  // 3 parámetros

C# determina qué versión llamar según los argumentos que le pases.

8.2 Ejemplo práctico: Calcular potencia

// Versión 1: Solo corriente (asume 230V monofásico)
double CalcularPotencia(double corriente)
{
    return 230.0 * corriente;
}

// Versión 2: Voltaje y corriente
double CalcularPotencia(double voltaje, double corriente)
{
    return voltaje * corriente;
}

// Versión 3: Voltaje, corriente y factor de potencia
double CalcularPotencia(double voltaje, double corriente, double factorPotencia)
{
    return voltaje * corriente * factorPotencia;
}

// Versión 4: Trifásico
double CalcularPotenciaTrifasica(double voltaje, double corriente, double factorPotencia)
{
    return Math.Sqrt(3) * voltaje * corriente * factorPotencia;
}

// Uso: C# elige automáticamente la versión correcta
double p1 = CalcularPotencia(10.0);                  // Usa versión 1
double p2 = CalcularPotencia(400.0, 10.0);           // Usa versión 2
double p3 = CalcularPotencia(230.0, 10.0, 0.85);     // Usa versión 3

8.3 Ejemplo: Convertir resistencia

// Versión 1: String a double
double ConvertirResistencia(string texto)
{
    return double.Parse(texto);
}

// Versión 2: De kΩ a Ω
double ConvertirResistencia(double kiloOhmios, bool esKilo)
{
    if (esKilo)
        return kiloOhmios * 1000.0;
    else
        return kiloOhmios;
}

// Uso
double r1 = ConvertirResistencia("470.5");         // Versión 1
double r2 = ConvertirResistencia(4.7, true);       // Versión 2: 4.7kΩ = 4700Ω

8.4 Reglas de sobrecarga

Permitido (diferentes parámetros):

void Funcion(int a)
void Funcion(double a)
void Funcion(int a, int b)
void Funcion(string a)

NO permitido (solo cambia el tipo de retorno):

int Funcion(int a)
double Funcion(int a)  //  ERROR: firma idéntica

Manos a la obra: Construyendo el proyecto

Vamos a crear una Librería de Funciones para Cálculos Eléctricos completa y reutilizable.

Paso 1: Estructura básica de la clase

using System;
using Eplan.EplApi.Base;
using Eplan.EplApi.ApplicationFramework;

public class BibliotecaElectrica
{
    // ========================================
    // CONSTANTES GLOBALES
    // ========================================

    private const double VOLTAJE_NOMINAL_MONOFASICO = 230.0;  // V
    private const double VOLTAJE_NOMINAL_TRIFASICO = 400.0;   // V
    private const double RESISTIVIDAD_COBRE = 0.018;          // Ω·mm²/m
    private const double RESISTIVIDAD_ALUMINIO = 0.028;       // Ω·mm²/m
    private const double CONVERSION_KW_HP = 1.341;            // 1 kW = 1.341 HP

    [Start]
    public void Ejecutar()
    {
        // Aquí probaremos las funciones
    }
}

Paso 2: Funciones de Ley de Ohm

// ========================================
// LEY DE OHM
// ========================================

// Calcular resistencia: R = V / I
double CalcularResistencia(double voltaje, double corriente)
{
    if (corriente == 0)
    {
        MessageBox.Show("Error: Corriente no puede ser cero");
        return 0;
    }
    return voltaje / corriente;
}

// Calcular voltaje: V = I × R
double CalcularVoltaje(double corriente, double resistencia)
{
    return corriente * resistencia;
}

// Calcular corriente: I = V / R
double CalcularCorriente(double voltaje, double resistencia)
{
    if (resistencia == 0)
    {
        MessageBox.Show("Error: Resistencia no puede ser cero");
        return 0;
    }
    return voltaje / resistencia;
}

Paso 3: Funciones de potencia (sobrecargadas)

// ========================================
// CÁLCULOS DE POTENCIA
// ========================================

// Potencia: P = V × I
double CalcularPotencia(double voltaje, double corriente)
{
    return voltaje * corriente;
}

// Potencia con factor de potencia: P = V × I × cos φ
double CalcularPotencia(double voltaje, double corriente, double factorPotencia)
{
    return voltaje * corriente * factorPotencia;
}

// Potencia solo con corriente (asume 230V)
double CalcularPotencia(double corriente)
{
    return VOLTAJE_NOMINAL_MONOFASICO * corriente;
}

// Potencia trifásica: P = √3 × V × I × cos φ
double CalcularPotenciaTrifasica(double voltaje, double corriente, double factorPotencia)
{
    return Math.Sqrt(3) * voltaje * corriente * factorPotencia;
}

// Potencia aparente: S = V × I
double CalcularPotenciaAparente(double voltaje, double corriente)
{
    return voltaje * corriente;
}

// Potencia reactiva: Q = √(S² - P²)
double CalcularPotenciaReactiva(double potenciaAparente, double potenciaActiva)
{
    return Math.Sqrt(Math.Pow(potenciaAparente, 2) - Math.Pow(potenciaActiva, 2));
}

Paso 4: Funciones de caída de tensión

// ========================================
// CAÍDA DE TENSIÓN
// ========================================

// Caída de tensión en cable de cobre
double CalcularCaidaTension(double longitud, double corriente, double seccion)
{
    // ΔV = 2 × L × I × ρ / S
    return (2 * longitud * corriente * RESISTIVIDAD_COBRE) / seccion;
}

// Caída de tensión especificando material
double CalcularCaidaTension(double longitud, double corriente, double seccion, string material)
{
    double resistividad;

    if (material.ToLower() == "aluminio")
    {
        resistividad = RESISTIVIDAD_ALUMINIO;
    }
    else
    {
        resistividad = RESISTIVIDAD_COBRE;
    }

    return (2 * longitud * corriente * resistividad) / seccion;
}

// Porcentaje de caída de tensión
double CalcularPorcentajeCaida(double caidaTension, double voltajeNominal)
{
    return (caidaTension / voltajeNominal) * 100.0;
}

// Sección mínima para caída máxima
double CalcularSeccionMinima(double longitud, double corriente, double caidaMaxima)
{
    // S = (2 × L × I × ρ) / ΔV
    return (2 * longitud * corriente * RESISTIVIDAD_COBRE) / caidaMaxima;
}

Paso 5: Funciones de conversión

// ========================================
// CONVERSIONES
// ========================================

// kW a HP
double ConvertirKWaHP(double potenciaKW)
{
    return potenciaKW * CONVERSION_KW_HP;
}

// HP a kW
double ConvertirHPaKW(double potenciaHP)
{
    return potenciaHP / CONVERSION_KW_HP;
}

// W a kW
double ConvertirWaKW(double potenciaW)
{
    return potenciaW / 1000.0;
}

// kW a W
double ConvertirKWaW(double potenciaKW)
{
    return potenciaKW * 1000.0;
}

// mm² a AWG (aproximado)
int ConvertirMM2aAWG(double seccionMM2)
{
    // Tabla simplificada
    if (seccionMM2 >= 10.0) return 8;
    if (seccionMM2 >= 6.0) return 10;
    if (seccionMM2 >= 4.0) return 12;
    if (seccionMM2 >= 2.5) return 14;
    if (seccionMM2 >= 1.5) return 16;
    return 18;
}

Paso 6: Funciones de validación (void)

// ========================================
// VALIDACIONES
// ========================================

void ValidarVoltaje(double voltaje)
{
    double minimo = VOLTAJE_NOMINAL_MONOFASICO * 0.90;  // -10%
    double maximo = VOLTAJE_NOMINAL_MONOFASICO * 1.10;  // +10%

    if (voltaje < minimo || voltaje > maximo)
    {
        MessageBox.Show(
            string.Format("ADVERTENCIA: Voltaje {0:F1}V fuera de rango ({1:F1}V - {2:F1}V)",
                voltaje, minimo, maximo),
            "Voltaje Anormal",
            MessageBoxButtons.OK,
            MessageBoxIcon.Warning
        );
    }
}

void ValidarCaidaTension(double caidaTension, double voltajeNominal)
{
    double porcentaje = CalcularPorcentajeCaida(caidaTension, voltajeNominal);

    if (porcentaje > 3.0)
    {
        MessageBox.Show(
            string.Format("ADVERTENCIA: Caída de tensión {0:F2}% excede el límite de 3%",
                porcentaje),
            "Caída Excesiva",
            MessageBoxButtons.OK,
            MessageBoxIcon.Warning
        );
    }
}

void MostrarResumenCircuito(string nombreCircuito, double voltaje, double corriente, double potencia)
{
    string mensaje = string.Format(
        "CIRCUITO: {0}\n\n" +
        "Voltaje: {1:F1}V\n" +
        "Corriente: {2:F1}A\n" +
        "Potencia: {3:F2}W ({4:F2}kW)",
        nombreCircuito,
        voltaje,
        corriente,
        potencia,
        ConvertirWaKW(potencia)
    );

    MessageBox.Show(mensaje, "Resumen del Circuito", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Paso 7: Función de prueba que usa toda la librería

[Start]
public void Ejecutar()
{
    string reporte = "=== BIBLIOTECA ELÉCTRICA - DEMOSTRACIÓN ===\n\n";

    // ========================================
    // PRUEBA 1: LEY DE OHM
    // ========================================

    double voltaje = 230.0;
    double corriente = 16.0;
    double resistencia = CalcularResistencia(voltaje, corriente);

    reporte += "LEY DE OHM:\n";
    reporte += string.Format("V={0}V, I={1}A → R={2:F2}Ω\n\n", voltaje, corriente, resistencia);

    // ========================================
    // PRUEBA 2: POTENCIA (SOBRECARGA)
    // ========================================

    double p1 = CalcularPotencia(corriente);  // Solo corriente
    double p2 = CalcularPotencia(voltaje, corriente);  // V e I
    double p3 = CalcularPotencia(voltaje, corriente, 0.85);  // V, I y cos φ

    reporte += "POTENCIA (FUNCIONES SOBRECARGADAS):\n";
    reporte += string.Format("CalcularPotencia({0}A) = {1:F2}W\n", corriente, p1);
    reporte += string.Format("CalcularPotencia({0}V, {1}A) = {2:F2}W\n", voltaje, corriente, p2);
    reporte += string.Format("CalcularPotencia({0}V, {1}A, 0.85) = {2:F2}W\n\n", voltaje, corriente, p3);

    // ========================================
    // PRUEBA 3: CAÍDA DE TENSIÓN
    // ========================================

    double longitud = 50.0;
    double seccion = 2.5;
    double caida = CalcularCaidaTension(longitud, corriente, seccion);
    double porcentajeCaida = CalcularPorcentajeCaida(caida, voltaje);

    reporte += "CAÍDA DE TENSIÓN:\n";
    reporte += string.Format("Cable: {0}mm², {1}m, {2}A\n", seccion, longitud, corriente);
    reporte += string.Format("Caída: {0:F2}V ({1:F2}%)\n\n", caida, porcentajeCaida);

    // ========================================
    // PRUEBA 4: CONVERSIONES
    // ========================================

    double potenciaKW = 7.5;
    double potenciaHP = ConvertirKWaHP(potenciaKW);

    reporte += "CONVERSIONES:\n";
    reporte += string.Format("{0}kW = {1:F2}HP\n", potenciaKW, potenciaHP);
    reporte += string.Format("{0}mm² ≈ AWG {1}\n\n", seccion, ConvertirMM2aAWG(seccion));

    // ========================================
    // PRUEBA 5: POTENCIA TRIFÁSICA
    // ========================================

    double voltajeTrifasico = 400.0;
    double corrienteTrifasica = 50.0;
    double fp = 0.85;
    double potenciaTrifasica = CalcularPotenciaTrifasica(voltajeTrifasico, corrienteTrifasica, fp);

    reporte += "POTENCIA TRIFÁSICA:\n";
    reporte += string.Format("V={0}V, I={1}A, cos φ={2}\n", voltajeTrifasico, corrienteTrifasica, fp);
    reporte += string.Format("P={0:F2}W ({1:F2}kW)\n\n", potenciaTrifasica, ConvertirWaKW(potenciaTrifasica));

    // ========================================
    // MOSTRAR REPORTE
    // ========================================

    MessageBox.Show(reporte, "Biblioteca Eléctrica", MessageBoxButtons.OK, MessageBoxIcon.Information);

    // ========================================
    // VALIDACIONES (VOID)
    // ========================================

    ValidarVoltaje(voltaje);
    ValidarCaidaTension(caida, voltaje);
    MostrarResumenCircuito("Circuito Principal", voltaje, corriente, p2);
}

Código completo del proyecto

(El código está completo en el archivo BibliotecaElectrica.cs)


Deep Dive: Entendiendo en profundidad

Recursividad

Una función puede llamarse a sí misma (recursión):

int Factorial(int n)
{
    if (n <= 1)
        return 1;
    else
        return n * Factorial(n - 1);  // Se llama a sí misma
}

// Factorial(5) = 5 × 4 × 3 × 2 × 1 = 120

Uso en ingeniería: Cálculos de serie/paralelo de componentes recursivos.

Expresiones lambda (funciones anónimas)

Funciones compactas sin nombre:

// Función normal
double Cuadrado(double x)
{
    return x * x;
}

// Lambda equivalente
Func<double, double> cuadrado = x => x * x;

// Uso
double resultado = cuadrado(5.0);  // 25.0

Mejores prácticas

1. Nombres descriptivos

// Mal
double Calc(double a, double b)

// Bien
double CalcularResistenciaParalelo(double resistencia1, double resistencia2)

2. Una función, una responsabilidad

// Mal: hace demasiadas cosas
void ProcesarYMostrarYGuardar(double valor)

// Bien: funciones separadas
double Calcular(double valor)
void Mostrar(double resultado)
void Guardar(double resultado)

3. Validar parámetros

double CalcularResistencia(double voltaje, double corriente)
{
    if (corriente == 0)
    {
        throw new ArgumentException("Corriente no puede ser cero");
    }
    return voltaje / corriente;
}

Recursos adicionales


Preguntas frecuentes

P: ¿Cuál es la diferencia entre función y método?

R: En C#, ambos términos se usan indistintamente. Técnicamente, un "método" es una función que pertenece a una clase.

P: ¿Puedo tener una función dentro de otra función?

R: No en C# estándar. Pero puedes usar funciones locales (características avanzadas) o lambdas.

P: ¿Cuántos parámetros puede tener una función?

R: No hay límite técnico, pero si tienes más de 4-5, considera usar un objeto o estructura para agruparlos.

P: ¿Qué pasa si olvido el return en una función no-void?

R: Error de compilación. Todas las rutas de código deben devolver un valor.

P: ¿Puedo sobrecargar cambiando solo el tipo de retorno?

R: No. La sobrecarga se basa en parámetros (tipo y cantidad), no en el tipo de retorno.


Checklist de completitud

Antes de pasar al siguiente capítulo, asegúrate de:

  • Entender qué es una función y para qué sirve
  • Poder crear funciones con parámetros y return
  • Saber cuándo usar void vs funciones con return
  • Comprender el scope de variables
  • Poder sobrecargar funciones
  • Usar parámetros opcionales
  • Haber ejecutado la biblioteca eléctrica
  • Poder agregar nuevas funciones a la librería
  • (Opcional) Haber intentado al menos un desafío

Última actualización: Enero 2025 Tiempo de lectura estimado: 55-65 minutos Código de ejemplo: code/cap-08/