Creación de Tipos de Datos Personalizados en Programación Avanzada
Clase 30 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#
13:47 min - 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
Viendo ahora - 31

Generación de Reportes con LINQ en C#
02:09 min
Etapa 9 – Creando una UI de Consola
Domina el cálculo de promedios por asignatura en C# con un enfoque claro: usar LINQ para agrupar evaluaciones, añadir resultados a un diccionario y evitar tipos anónimos creando una clase específica. Verás por qué depender de object y casting complica el trabajo y cómo una estructura tipada hace el código más legible, seguro y mantenible.
¿Cómo agregar promedios de alumnos al diccionario de respuesta?
Para organizar la salida se renombra la lista como promediosAlumnos y se adiciona al diccionario de respuesta usando como key el nombre de la asignatura. La clave representa la asignatura, y el valor es la lista de promedios de sus alumnos.
- Usar un diccionario con key string para la asignatura.
- Guardar listas de promedios de alumnos como value.
- Validar que la key sea el nombre de la asignatura.
// Ejemplo de estructura de carga
var promediosAlumnos = new List<AlumnoPromedio>();
respuesta.Add(asignaturaNombre, promediosAlumnos);
¿Qué clave usar en el diccionario por asignatura?
- La key es el nombre de la asignatura.
- Evita claves ambiguas: usa el nombre exacto de la asignatura.
- Asegura unicidad por asignatura para consultar sin errores.
¿Cómo iterar los pares key-value con foreach?
- Al recorrer la estructura, usa item.Key para la asignatura e item.Value para la lista de alumnos con promedio.
- Diferencia claramente asignatura, ID de alumno y promedio.
foreach (var item in listaPromediosPorAsignatura)
{
var asignatura = item.Key; // nombre de la asignatura
var alumnosConPromedio = item.Value; // List<AlumnoPromedio>
}
¿Por qué evitar tipos anónimos y usar una clase AlumnoPromedio?
Cuando la lista interna usa tipos anónimos, el sistema la trata como object. Al intentar acceder a propiedades, no hay ayuda del compilador y terminas haciendo casting, lo que es frágil y propenso a fallos si la implementación cambia. En su lugar, define una clase concreta.
- Los tipos anónimos son locales al método.
- Fuera del método, solo quedan como object.
- El casting con as requiere comprobaciones de nulos y añade complejidad.
¿Qué problema causa object y casting en tiempo de ejecución?
- No hay acceso directo a propiedades.
- Alto riesgo de errores si cambia la forma de los datos.
foreach (var alum in item.Value)
{
var tmp = alum as Alumno; // puede ser null
if (tmp != null)
{
// Acceso a propiedades, pero con riesgo y ruido.
}
}
¿Cómo definir AlumnoPromedio y mapear propiedades?
Se crea un tipo fuerte y simple. Se discutió el encapsulamiento, pero para el ejercicio se dejó como campos públicos para reducir sobrecarga.
public class AlumnoPromedio
{
public float promedio;
public string alumnoId;
public string alumnoNombre; // se llena al enriquecer el grupo
}
- promedio: promedio final del alumno en la asignatura.
- alumnoId: identifica al alumno de forma estable.
- alumnoNombre: se agrega para lectura humana.
var ap = new AlumnoPromedio {
alumnoId = keyAlumno, // obtenido del agrupamiento
alumnoNombre = nombreAlumno, // enriquecido en el grupo
promedio = promedioCalculado
};
¿Cómo usar LINQ para agrupar por asignatura y calcular promedios?
La clave está en agrupar por asignatura y, dentro del grupo, generar una clave compuesta con ID de alumno y nombre para poder poblar ambos valores. Así se evita depender de datos fuera del grupo y se completa AlumnoPromedio correctamente.
- Agrupar por asignatura y por alumno con clave compuesta.
- Calcular el promedio con las notas del grupo.
- Mapear a AlumnoPromedio y adicionar al diccionario.
var consulta = evaluaciones
.GroupBy(eval => new {
asignatura = eval.Asignatura.Nombre,
uniqueId = eval.Alumno.Id,
nombre = eval.Alumno.Nombre
})
.Select(g => new {
g.Key.asignatura,
alumno = new AlumnoPromedio {
alumnoId = g.Key.uniqueId,
alumnoNombre = g.Key.nombre,
promedio = g.Average(e => e.Nota)
}
});
// Ensamblar el diccionario final por asignatura
var respuesta = new Dictionary<string, List<AlumnoPromedio>>();
foreach (var item in consulta)
{
if (!respuesta.TryGetValue(item.asignatura, out var lista))
{
lista = new List<AlumnoPromedio>();
respuesta[item.asignatura] = lista;
}
lista.Add(item.alumno);
}
¿Qué consultas LINQ se aplicaron con keywords?
- from, select, where: para proyectar y filtrar datos.
- group by: para agrupar por asignatura y alumno.
- distinct: para eliminar duplicados donde correspondía.
- order by: ya utilizado en ejercicios previos para ordenar listas.
¿Qué se validó en el resultado final?
- Asignaturas como Matemáticas y Castellano con su lista de alumnos.
- Cada entrada con alumnoNombre, alumnoId y promedio.
- Comprobación visual de nombres y promedios cargados correctamente.
¿Te gustaría que preparemos una variante que incluya ordenamiento por promedio o filtros por asignatura específica? Deja tus dudas o ideas en los comentarios y armamos la siguiente mejora juntos.