Manejo Avanzado de Métodos y Parámetros en Programación

Clase 11 de 35Curso de C# con .Net Core 2.1

Resumen

Mejora el rendimiento y la claridad del código en C# al controlar qué objetos cargar, evitar sobrecarga innecesaria y devolver múltiples valores con precisión. Con parámetros opcionales, tuplas y parámetros de salida, se logra un método flexible que ahorra memoria y tiempo de ejecución sin perder trazabilidad en el depurador.

¿Cómo controlar qué objetos cargar con parámetros opcionales?

La idea central es hacer granular la carga de datos de la escuela: evaluaciones, alumnos, asignaturas y cursos. Se parte de una sobrecarga existente y se evoluciona hacia una sola firma con parámetros opcionales booleanos que por defecto son verdaderos. Así, se evita la duplicación y se gana flexibilidad.

  • Escuela siempre incluida.
  • Flags: traerEvaluaciones, traerAlumnos, traerAsignaturas, traerCursos.
  • Mejor rendimiento: no se cargan objetos que no se necesitan.

Código base con parámetros opcionales y lógica condicional:

List<ObjetoEscuela> GetObjetosEscuela(
    bool traerEvaluaciones = true,
    bool traerAlumnos = true,
    bool traerAsignaturas = true,
    bool traerCursos = true)
{
    var lista = new List<ObjetoEscuela>();
    lista.Add(escuela); // escuela siempre.

    if (traerCursos)
    {
        lista.AddRange(escuela.Cursos);
        foreach (var curso in escuela.Cursos)
        {
            if (traerAsignaturas) lista.AddRange(curso.Asignaturas);

            // Si no traigo alumnos pero sí evaluaciones, igual recorro alumnos.
            if (traerAlumnos || traerEvaluaciones)
            {
                foreach (var alumno in curso.Alumnos)
                {
                    if (traerAlumnos) lista.Add(alumno);
                    if (traerEvaluaciones) lista.AddRange(alumno.Evaluaciones);
                }
            }
        }
    }

    return lista;
}

¿Qué ventaja ofrecen los parámetros opcionales?

  • Una sola firma en lugar de múltiples sobrecargas.
  • Llamadas más legibles y flexibles.
  • Menos objetos en memoria cuando no se requieren.

¿Cómo se verifica el resultado con el depurador?

  • Con todo activado: la lista mostró 1622 objetos cargados, incluyendo evaluaciones.
  • Sin evaluaciones: el resultado bajó a 88 objetos.
  • Todo en false: se obtuvo 1 objeto: la escuela Platzi Academy.

¿Qué pasa si no traigo alumnos pero sí evaluaciones?

  • No se agregan alumnos a la lista.
  • Se recorre cada curso y sus alumnos para sumar o agregar evaluaciones.
  • La lógica de negocio se mantiene sin poblar entidades innecesarias.

¿Cómo devolver múltiples valores: tuplas o parámetros de salida?

Se exploran dos enfoques para conocer cuántos elementos se cargan por tipo. Primero, una tupla que devuelve la lista y el conteo de evaluaciones. Luego, parámetros de salida para obtener todos los conteos: evaluaciones, asignaturas, alumnos y cursos.

¿Cómo usar tuplas para lista y conteo?

  • Se acumula el conteoEvaluaciones sumando alumno.Evaluaciones.Count.
  • La firma devuelve: (lista, conteoEvaluaciones).
(List<ObjetoEscuela> lista, int conteoEvaluaciones) GetObjetosEscuela(
    bool traerEvaluaciones = true,
    bool traerAlumnos = true,
    bool traerAsignaturas = true,
    bool traerCursos = true)
{
    var lista = new List<ObjetoEscuela>();
    int conteoEvaluaciones = 0;

    lista.Add(escuela);
    if (traerCursos)
    {
        lista.AddRange(escuela.Cursos);
        foreach (var curso in escuela.Cursos)
        {
            if (traerAsignaturas) lista.AddRange(curso.Asignaturas);
            if (traerAlumnos || traerEvaluaciones)
            {
                foreach (var alumno in curso.Alumnos)
                {
                    if (traerAlumnos) lista.Add(alumno);
                    if (traerEvaluaciones)
                    {
                        lista.AddRange(alumno.Evaluaciones);
                        conteoEvaluaciones += alumno.Evaluaciones.Count;
                    }
                }
            }
        }
    }

    return (lista, conteoEvaluaciones);
}
  • Si traerEvaluaciones es false: el conteo es 0.
  • Si es true: se observaron 960 evaluaciones como conteo total.

¿Cuándo preferir parámetros de salida out?

  • Cuando se requieren varios conteos a la vez con una sola pasada.
  • Regla en C#: los parámetros opcionales deben ir al final, los requeridos primero.
  • Obligatorio asignar todos los parámetros marcados con out.
List<ObjetoEscuela> GetObjetosEscuela(
    out int conteoEvaluaciones,
    out int conteoAsignaturas,
    out int conteoAlumnos,
    out int conteoCursos,
    bool traerEvaluaciones = true,
    bool traerAlumnos = true,
    bool traerAsignaturas = true,
    bool traerCursos = true)
{
    conteoEvaluaciones = conteoAsignaturas = conteoAlumnos = 0; // asignación múltiple.
    conteoCursos = traerCursos ? escuela.Cursos.Count : 0;

    var lista = new List<ObjetoEscuela>();
    lista.Add(escuela);

    if (traerCursos)
    {
        lista.AddRange(escuela.Cursos);
        foreach (var curso in escuela.Cursos)
        {
            if (traerAsignaturas)
            {
                lista.AddRange(curso.Asignaturas);
                conteoAsignaturas += curso.Asignaturas.Count;
            }

            if (traerAlumnos || traerEvaluaciones)
            {
                foreach (var alumno in curso.Alumnos)
                {
                    if (traerAlumnos) lista.Add(alumno);
                    if (traerEvaluaciones)
                    {
                        lista.AddRange(alumno.Evaluaciones);
                        conteoEvaluaciones += alumno.Evaluaciones.Count;
                    }
                }
                conteoAlumnos += curso.Alumnos.Count;
            }
        }
    }

    return lista;
}

¿Qué habilidades y conceptos se fortalecen?

  • Sobrecarga de métodos: cuándo evitarla con parámetros opcionales.
  • Parámetros opcionales: valores por defecto para controlar carga.
  • Parámetros de salida (out): múltiples resultados garantizados por contrato.
  • Tuplas: retorno compacto de varios valores.
  • Control de flujo con if y foreach: decisiones granulares por entidad.
  • Acumuladores y conteos: sumas incrementales con Count.
  • Firma del método: orden correcto de parámetros requeridos y opcionales.
  • Depuración: verificación de tamaños de lista y conteos.
  • Rendimiento: evitar poblar listas innecesariamente.
  • Próximo objetivo: diccionario de datos con una enumeración para clasificar objetos.

¿Qué se anticipa con enumeración y diccionario de datos?

Se prepara la creación de un diccionario de datos basado en una enumeración para clasificar y acceder a colecciones por tipo. Este enfoque facilita consultas específicas y organiza la estructura de datos para escenarios de lógica compleja.

¿Te gustaría sugerir casos de uso para los conteos o proponer la estructura de la enumeración? Comparte tus ideas en los comentarios.