Foreach anidado para diccionarios en C#
Clase 18 de 35 • Curso de C# con .Net Core 2.1
Contenido del curso
Etapa 5 – POO reutilicemos nuestro código
- 2

Herencia para reutilizar código C#
10:30 min - 3

Herencia y Polimorfismo en Programación Orientada a Objetos
11:42 min - 4

Polimorfismo en Programación Orientada a Objetos
13:17 min - 5

Casting en C#: cuándo funciona y cuándo falla
07:09 min - 6

Conversiones seguras en C# con is y as
12:44 min - 7

Sobrescribir ToString para depuración en C#
08:15 min
Etapa 6- Ajustes y funcionalidad
Etapa 7 – Preparando información para nuestros reportes
- 11

Manejo Avanzado de Métodos y Parámetros en Programación
15:43 min - 12

Manejo de Parámetros de Salida en Visual Studio Code
04:38 min - 13

Sobrecarga de Métodos para Parámetros de Salida Opcionales
05:51 min - 14

Optimización de Listas: Buenas Prácticas en C#
04:16 min - 15

Dictionary: cómo funciona en C#
11:14 min - 16

Diccionarios con polimorfismo en C#
10:48 min - 17

Uso de Constantes y Enumeraciones para Optimizar Diccionarios en C#
11:33 min - 18

Foreach anidado para diccionarios en C#
Viendo ahora - 19

Depuración de diccionarios en C#
09:37 min - 20

Parámetro opcional para controlar impresión en C#
11:47 min - 21

Cómo usar switch en lugar de if/else
14:30 min - 22

Números aleatorios y eventos en C#
12:52 min - 23

Diccionarios y Refactoring en Programación Básica
02:13 min
Etapa 8 – Consultas
- 24

Cómo crear un reporteador en C sharp
11:42 min - 25

Generación segura de reportes en sistemas de información
10:21 min - 26

Construcción de reportes con LINQ en C#
11:48 min - 27

Diccionario con evaluaciones por asignatura
08:32 min - 28

Tipos anónimos en LINQ para reportes complejos
10:52 min - 29

Cálculo del Promedio de Notas Agrupadas por Alumno y Asignatura
10:46 min - 30

Creación de Tipos de Datos Personalizados en Programación Avanzada
12:05 min - 31

Generación de Reportes con LINQ en C#
02:09 min
Etapa 9 – Creando una UI de Consola
Construir un diccionario robusto en C# que agrupe escuela, cursos, alumnos, asignaturas y evaluaciones exige orden y buenas prácticas. Aquí verás cómo evitar claves duplicadas, aprovechar foreach, usar AddRange y aplicar cast de forma segura para consolidar colecciones, además de depurar en Visual Studio con confianza.
¿Cómo se construye el diccionario de objetos?
Para iniciar, se define un diccionario cuya llave es una enumeración y cuyo valor es una colección de objetos base. La carga empieza con la escuela, sigue con los cursos y luego profundiza en las colecciones anidadas.
- La llave es una enumeración que representa tipos: escuela, curso, alumno, asignatura y evaluación.
- El valor es una colección del tipo común, por ejemplo EscuelaBase, usando cast cuando haga falta.
- Truco útil: un array de una posición también es IEnumerable, ideal para agregar una sola escuela.
// Diccionario con enum como llave y IEnumerable<EscuelaBase> como valor
var diccionario = new Dictionary<LlaveDiccionario, IEnumerable<EscuelaBase>>();
// Escuela como IEnumerable usando un array de una posición
diccionario.Add(LlaveDiccionario.Escuela, new EscuelaBase[] { escuela });
// Cursos convertidos a EscuelaBase
diccionario.Add(LlaveDiccionario.Curso, escuela.Cursos.Cast<EscuelaBase>());
¿Por qué usar foreach para cursos y alumnos?
Cada curso tiene múltiples alumnos, por eso se recorre con foreach sobre escuela.Cursos y, dentro, sobre curso.Alumnos. Aunque un bloque de una sola línea no requiere llaves, mantenerlas mejora la legibilidad y previene errores cuando el bloque crezca.
¿Cómo se agregan asignaturas, alumnos y evaluaciones sin duplicar claves?
Agregar dentro del bucle con diccionario.Add para la misma llave provoca una excepción por clave duplicada. La solución: acumular en listas temporales con AddRange y asignar una sola vez por llave al final.
- Evitar diccionario.Add repetido dentro de los bucles.
- Crear listas temporales antes de recorrer los cursos.
- Acumular asignaturas, alumnos y evaluaciones con AddRange.
- Asignar una sola vez por llave después de terminar los bucles.
// Listas temporales
var tmpAsignaturas = new List<Asignatura>();
var tmpAlumnos = new List<Alumno>();
var tmpEvaluaciones = new List<Evaluación>();
foreach (var cur in escuela.Cursos)
{
// Acumular asignaturas y alumnos del curso
tmpAsignaturas.AddRange(cur.Asignaturas);
tmpAlumnos.AddRange(cur.Alumnos);
// Acumular evaluaciones de cada alumno del curso
foreach (var alum in cur.Alumnos)
{
tmpEvaluaciones.AddRange(alum.Evaluaciones);
}
}
// Asignar una sola vez por clave
diccionario[LlaveDiccionario.Asignatura] = tmpAsignaturas.Cast<EscuelaBase>();
diccionario[LlaveDiccionario.Alumno] = tmpAlumnos.Cast<EscuelaBase>();
diccionario[LlaveDiccionario.Evaluación] = tmpEvaluaciones.Cast<EscuelaBase>();
¿Dónde ubicar la lógica de evaluaciones?
Las evaluaciones dependen de los alumnos y estos de los cursos. Por eso, conviene crear la lista temporal de evaluaciones antes de recorrer cursos, llenarla durante los bucles y asignarla al diccionario al final. Así evitas múltiples listas y la violación de integridad por llaves repetidas.
¿Qué método usar para agregar: Add o asignación por índice?
Cuando necesitas poner el contenido una única vez por clave, acumula primero y luego asigna una sola vez. Usar directamente diccionario.Add dentro del foreach provoca colisiones; en cambio, la asignación única al final respeta la unicidad de la clave.
¿Cómo depurar y validar el diccionario en Visual Studio?
La verificación paso a paso en Visual Studio ayuda a confirmar que cada colección se llena correctamente y a detectar excepciones por clave duplicada.
- Punto de interrupción en el método que construye el diccionario.
- Ejecución paso a paso con F10 para observar el flujo.
- Inspección de llaves: escuela y curso primero, luego asignatura, alumno y evaluación.
- Formateo y orden del código para mayor claridad: primero asignaturas, luego alumnos, y al final evaluaciones.
- Revisión de estados intermedios: contar elementos acumulados en listas temporales durante la iteración.
¿Qué habilidades y conceptos se refuerzan?
- Manejo de colecciones con IEnumerable y array de una posición.
- Conversión segura con cast hacia el tipo base común.
- Control de flujo con foreach anidados y buenas prácticas de llaves.
- Acumulación con listas temporales y uso de AddRange.
- Prevención de claves duplicadas al llenar un diccionario.
- Depuración con puntos de interrupción y lectura de excepciones.
¿Te gustaría ver variantes de esta estrategia con filtros o proyecciones por tipo? Comparte tus dudas o tu caso y lo revisamos juntos.