You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

1 Días
10 Hrs
6 Min
30 Seg

Impresión de objetos de un diccionario

20/35
Resources

How to handle optional printing of evaluations in C#?

In a continuous development environment and in robust projects, managing data printing is a crucial challenge. The goal is to avoid overloading the console with excessive information and to maintain an orderly workflow. In this context, one of the key issues is deciding when to print certain types of data, such as evaluations.

To address this problem, it is recommended to use optional parameters in methods that act as switches, deciding whether or not to print certain information. This approach not only organizes the code, but provides flexibility over the amount of data displayed. In the following, we will describe, step by step, how to implement this functionality in C#.

How to add optional parameters to control printing?

  • Parameter definition: Start by adding an optional parameter in the relevant method, for example, bool printEvaluations = false;.
  • Filtering by object type: Then, check if the current object is an evaluation: if (printEvaluations && val is Evaluation).
  • Non-essential information: If the data are not evaluations, unless otherwise specified, they should not be printed.
public void PrintData(IEnumerable<object> objects, bool printEvaluations = false){ foreach (var val in objects) { if (val is Evaluation && printEvaluations) { Console.WriteLine(val.ToString()); } else if (!(val is Evaluation)) { Console.WriteLine(val.ToString()); } }} }

What errors can arise and how to correct them?

When implementing this filter, some logical errors may arise that must be corrected. Let's look at the most common ones:

  • Incorrect conditions: Often, logic can be structured in such a way that other objects are not printed due to errors in the design of if-else conditions.
  • Residual data in the console: Data from previous runs may be printed. It is recommended to clear the console regularly to avoid confusion.
Console.Clear(); // Use before each new execution.

How to customize printing for different types of objects?

An effective approach is to define specific treatments for various data types. For example, print only the name for objects of type Student. This is achieved within the cycle that iterates over the objects.

  • Custom printing by object type:
    • If the object is a School, print the entire contents.
    • If it is a Student, only the name.
    • Apply different treatments to other types, according to the need.
foreach (var val in objects){ if (val is Evaluation && printEvaluations) { Console.WriteLine($"Evaluation: {val.ToString()}"); } else if (val is School) { Console.WriteLine($"School: {val.ToString()}"); } else if (val is Student) { Console.WriteLine($"Student: {((Student)val).Name}"); } else { Console.WriteLine(val.ToString()); } }}

When to use 'switch' instead of multiple 'if'?

In situations with multiple conditions, switch is preferred over if-else blocks because of its ability to optimize code readability and maintainability. Using switch on the object type ensures that specific actions are executed more efficiently.

switch (val.GetType().ToString()){ case "Evaluation": if (printEvaluations) Console.WriteLine($"Evaluation: {val.ToString()}"); break; case "School": Console.WriteLine($"School: {val.ToString()}"); break; case "Student": Console.WriteLine($"Student: {((Student)val).Name}"); break; default: Console.WriteLine(val.ToString()); break;}

This structure is not only more readable, but significantly improves program performance by addressing each possible object type with precision and clarity.

Exploring these strategies provides more granular control over data flow and encourages clean, functional coding in complex projects. Adopting these practices will enable developers to refine their skills and increase efficiency in their C# projects.

Contributions 43

Questions 0

Sort by:

Want to see more contributions, questions and answers from the community?

if(!(val is Evaluacion) || ImprimirEval)
                        Console.WriteLine(val);

Me a costado mucho seguir el curso.!

Es más sencillo así, desde mi humilde opinión:

if ((impEval && val is Evaluacion) || !(val is Evaluacion)) 
                        Console.WriteLine($"{obj.Key} => {val}");

Considero que la solucion es ineficiente porque entra al segundo for aunque estemos en la llave que no queremos imprimir. I checa 1 por uno el tipo del objeto.

Podemos optimizarlo con una verficacion por llave del diccionario y usando la palabra clave continue para que pase a la siguiente llave.

Ser veria algo asi.

Incluso lo podemos optimizar aun mas poniendo todo en un solo if con el operador OR.

Con esta solucion no entra al otro for y por lo tanto es mucho mas eficiente la funcion haciendo menos operaciones.

Lo hice de esta manera

        public void imprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoColegioBase>> dicc, bool eval = false)
        {
            foreach (var item in dicc)
            {
                Printer.EscribirTitulo(item.Key.ToString());
                foreach (var val in item.Value)
                {
                    if((val is Evaluacion && eval) || !(val is Evaluacion))
                    {
                        Console.WriteLine($"{val}");
                    }
                }
            }
        }

Esta es la forma en que lo hice sin usar IF

 foreach (var val in item.Value)
                {
                    var indice=val.GetType().ToString().LastIndexOf('.')+1;
                    if (!(val is Evaluacion) || impEvaluacion)
                       Console.WriteLine(val.GetType().ToString().ToUpper().Substring(indice) + " : " + val);
                 
                }```
Considero que no está mal la clase de miniproyectos que se realizan en este curso y como se abordan, pero en este caso creo que enreda demasiado, y trata de forzar el incluir conceptos en donde es complicado asimilar el ejemplo real.

Asi me quedó.

public void ImprimirDiccionario(Dictionary<LLaveDiccionario,List<ObjetoEscuelaBase>> dic,
            bool imprEval=false)
        {
            foreach (var obj in dic)
            {
                Printer.WriteTitle(obj.Key.ToString());
                foreach (var val in obj.Value)
                {
                    if(imprEval || !(val is Evaluación))//Imprime todos los objetos si imprEval es verdadero sino imprime solo no imprime Evaluaciones.
                        System.Console.WriteLine(val);
                }
            }
            
        }```

pues yo compare si lo que querian era igual al tipo de objeto que estaba en el bucle:

        public void PrintDic(Dictionary<TypeOfSchoolObjets,IEnumerable<ObjetoEscuelaBase>> diccionario, TypeOfSchoolObjets tipo =TypeOfSchoolObjets.Evaluacion )
        {
            var say = new List<ObjetoEscuelaBase>();
            foreach (var item in diccionario)
            {
                say = new List<ObjetoEscuelaBase>();
                if (tipo == item.Key)
                {    
                    foreach (var obj in item.Value)
                    {
                        say.Add(obj);
                    }
                Displays.printObjList(say,item.Key + "");
                }
            }
        }

Si por algún motivo no te muestra la calificación en el objeto evaluación, es porque hay que hacer override al método ToString de la clase Evaluacion para que te mueste lo que quieres.

Lo hice de esta manera

public void ImprimirDiccionario(Dictionary<LlaveDic, IEnumerable<ObjetoEscuelaBase>> dic, LlaveDic llaveDic)
        {
            var diccionario = dic.Where(x => x.Key is LlaveDic.Escuela);
            switch (llaveDic)
            {
                case LlaveDic.Cursos:
                    diccionario = dic.Where(x => x.Key is LlaveDic.Cursos);
                    break;
                case LlaveDic.Asignaturas:
                    diccionario = dic.Where(x => x.Key is LlaveDic.Asignaturas);
                    break;
                case LlaveDic.Alumnos:
                    diccionario = dic.Where(x => x.Key is LlaveDic.Alumnos);
                    break;
                case LlaveDic.Evaluaciones:
                    diccionario = dic.Where(x => x.Key is LlaveDic.Evaluaciones);
                    break;
                default:
                    break;
            }
            foreach (var k in diccionario)
            {
                Console.WriteLine(k.Key.ToString());
                foreach (var v in k.Value)
                {
                    Console.WriteLine(v);
                }
            }
        }
public void ImprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dict, bool imprimirEvaluaciones = false)
{
    foreach (var obj in dict)
    {
        Printer.WriteTitle($"{obj.Key}");
        foreach (var item in obj.Value)
        {
            if (imprimirEvaluaciones || obj.Key != LlaveDiccionario.Evaluacion)
                Console.WriteLine($"{item}");
        }
    }
}

if(!(!imprimirEvaluaciones && val is Evaluación))

En mi caso la hice así

        public void ImprimirDiccionario(Dictionary<LlaveDic, IEnumerable<ObjetoEscuelaBase>> dic,
            bool traeEvaluaciones = true,
            bool traeAlumnos = true,
            bool traeAsignaturas = true,
            bool traeCursos = true)
        {
            foreach (var keyValPair in dic)
            {
                Printer.WriteTitle(keyValPair.Key.ToString()); // va a imprimir, por ejemplo Curso, Escuela, etc.
                foreach (var val in keyValPair.Value)
                {
                    // ! aca iteramos dentro de los values del diccionario, que en este caso, son ObjetosEscuelaBase
                    if (val is Curso && traeCursos) // ejemplo clarisimo de downcasting
                    {
                        Curso cur = (Curso)val;
                        System.Console.WriteLine($"Curso: {cur.Nombre}      Alumnos: {cur.Alumnos.Count}");
                    }
                    if (val is Alumno && traeAlumnos)
                    {
                        Alumno alu = (Alumno)val;
                        double avg = SacarPromedioAlumno(alu.Evaluaciones);
                        System.Console.WriteLine($"Curso: {alu.Nombre}      Evaluaciones: {avg}");
                    }
                    if (val is Asignatura && traeAsignaturas)
                    {
                        Asignatura mat = (Asignatura)val;
                        System.Console.WriteLine($"Materia: {mat.Nombre}");
                    }
                    if (val is Evaluación && traeEvaluaciones)
                    {
                        Evaluación e = (Evaluación)val;
                        System.Console.WriteLine($"Nota: {e.Nota}      Materia: {e.Asignatura.Nombre}");
                    }
                    // si lo que quiseramos hacer es ya sea ordenar los resultados 
                    // yo agregaria cada objeto a una lista particular de cada objeto, 
                    // y despues un lindo foreach para imprimir de a listas, entones que lo que tengo 
                    // ahora quede como un "creador de listas" y hacer otra funcion que imprima las listas, 
                    // pero como no soy programador no opino.
                }
            }
        }

En mi caso hice la funcion de esta forma.

public void ImprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dic,
                    bool imprimirEvaluaciones = false,
                    bool imprimirCursos = false,
                    bool imprimirAsignaturas = false,
                    bool imprimirAlumnos = false)
        {
            foreach(var obj in dic)
            {
                Printer.WriteTitle(obj.Key.ToString());

                foreach(var value in obj.Value)
                {
                    if(value is Evaluacion  && !imprimirEvaluaciones) continue;
                    if(value is Curso       && !imprimirCursos) continue;
                    if(value is Asignatura  && !imprimirAsignaturas) continue;
                    if(value is Alumno      && !imprimirAlumnos) continue;
                    Console.WriteLine(value);
                }
            }
        }

Aunque aun muestra los carteles de titulo, estoy viendo como modificar eso.

🤯

Asi me funciona

<public void ImprimirDiccionario(Dictionary<LlavesDiccionario, IEnumerable<ObjetoEscuelaBase>> dic,
        bool imprEval = false){
            foreach (var obj in dic)
            {
                Printer.DrawTitle(obj.Key.ToString());
                
                
                foreach(var valor in obj.Value)
                {
                    if(imprEval == true){
                        Console.WriteLine(valor);
                    }
                    else{
                        dic.Remove(LlavesDiccionario.Evaluaciones);
                        Console.WriteLine(valor);
                    }   
                }
            }
        }>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int sum = 0;
            int numero1 = 0; int numero2 = 0; int numero3 = 0; int numero4 = 0;
           
            {
                Console.WriteLine("Primer Parcial");
                numero1 = Int32.Parse(Console.ReadLine());
            }
            if (numero1 > 15 == true)
            {
                Console.WriteLine("Calificacion Invalida");
                Console.WriteLine("Introduzca Nuevamente");
                numero1 = Int32.Parse(Console.ReadLine());
            }
           

            {
                Console.WriteLine("Segundo Parcial");
                numero2 = Int32.Parse(Console.ReadLine());
            }
            if (numero2 > 15 == true)
            {
                Console.WriteLine("Calificacion Invalida");
                Console.WriteLine("Introduzca Nuevamente");
                numero2 = Int32.Parse(Console.ReadLine());
            }
           
            {
                Console.WriteLine("Practica");
                numero3 = Int32.Parse(Console.ReadLine());
            }
            if (numero3 > 30 == true)
            {
                Console.WriteLine("Calificacion Invalida");
                Console.WriteLine("Introduzca Nuevamente");
                numero3 = Int32.Parse(Console.ReadLine());
            }
           
            {
                Console.WriteLine("Examen Final");
                numero4 = Int32.Parse(Console.ReadLine());
            }
            if (numero4 > 40 == true)
            {
                Console.WriteLine("Calificacion Invalida");
                Console.WriteLine("Introduzca Nuevamente");
                numero4 = Int32.Parse(Console.ReadLine());
            }

            {
                sum = numero1 + numero2 + numero3 + numero4;
                Console.WriteLine("Su Calificacion es : {0}", sum);
            }


            if (sum <= 60 == true)
            {
                Console.WriteLine("Reprobado ");
            }
            else
                if (sum <= 69 == true)
                {
                    Console.WriteLine("Extraordinario");
                }
                else
                   
                     if (sum <= 95 == true)
                            {
                                Console.WriteLine("Aprobado");
                            }
                            else
                                if (sum <= 100 == true)
                                {
                                    Console.WriteLine("Excelente");
                                }

            Console.ReadKey();

        }
    }
}```

Hola buen día

tengo este problema:

Codigo:

public void ImprimirDiccionario(Dictionary<LlavesDiccionario,IEnumerable<ObjetoEscuelaBase>> dic,
bool imprEval = false)
{
foreach (var obj in dic)
{
Printer.WriteTitle(obj.Key.ToString());
//Console.WriteLine(obj);
foreach (var val in obj.Value)
{
if ( val is Evaluacion){
if (imprEval)
Console.WriteLine(val);
}
else
Console.WriteLine(val);
}
}
}

al compilar me sale este error:

<h1>Pais: Colombia, Ciudad: Bogota</h1> <h1>| Curso |</h1>

Unhandled exception. System.InvalidCastException: Unable to cast object of type ‘System.Char’ to type ‘CoreEscuela.Entidades.ObjetoEscuelaBase’.
at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext()
at CoreEscuela.EscuelaEngine.ImprimirDiccionario(Dictionary`2 dic, Boolean imprEval) in D:\cursoPlatzi\platzi\CoreEscuela\App\EscuelaEngine.cs:line 67
at CoreEscuela.Program.Main(String[] args) in D:\cursoPlatzi\platzi\CoreEscuela\Program.cs:line 50
PS D:\cursoPlatzi\platzi\CoreEscuela>

Hola, aquí mi implementación: Si valor es de tipo Evaluación y printEvaluacion es falso, hago que el ciclo se continúe con el siguiente valor con la palabra reservada continue. En caso contrario, que imprima el valor llano y plano, anexo código:

public void ImprimirDiccionario( Dictionary< LlaveDiccionario, IEnumerable<ObjetoEscuelaBase> > dicc, bool printEval = false)
        {
            foreach (var obj in dicc)
            {
                Printer.WriteTitle( obj.Key.ToString() );
                foreach (var val in obj.Value)
                {
                    if ( val is Evaluacion && !printEval )
                    {
                        continue;
                    }
                    else
                    {
                        Console.WriteLine( val );
                    }
                }
            }
        }
foreach(var val in obj.Value)
                {
                    if(imprimirEvaluaciones == false)
                    {
                        if ( !(val is Evaluacion) )
                            Console.WriteLine(val);
                    }
                        
                }

para el foreach yo usaría el continue; para cuando es evaluación y no quiero imprimirlo, pase al siguiente ciclo de esta manera

 public void PrintDictionary( Dictionary<DictionaryKeys, IEnumerable<SchoolBase>> dic, bool printEval = false){
            foreach(var obj in dic){
                Printer.WriteTitle(obj.Key.ToString());
             
                foreach(var pair in obj.Value){
                    if(pair is Evaluations && !printEval)
                        continue; 
                    else
                        Console.WriteLine(pair);  
                }
            }
        }
 foreach (var obj in dic)
                {
                    Console.WriteLine(obj.Key.ToString());
                    Console.WriteLine(obj);
                    foreach (var kvp in obj.Value)
                    {
                        if (ImpriEval && kvp is Evaluación)
                        {
                            Console.WriteLine(kvp);
                        }else if(!(kvp is Evaluación))
                        {
                            Console.WriteLine(kvp);
                        }
                    }
                }

yo lo hice asi XD

Para hacer la impresion de los datos de un dictionary lo intentaria de la siguiente manera

Dictionary<string, string> datos = new Dictionary<string, string>();
datos.Add(“1”, “Mensaje uno”);
datos.Add(“2”, “Mensaje dos”);

        Console.WriteLine(datos.Values.ToString());

Resultadò

‘Estudiantes.exe’ (CLR v4.0.30319: DefaultDomain): ‘C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: DefaultDomain): ‘C:\Users\Sem-6-INGENIERIAINDU\source\repos\Estudiantes\Estudiantes\bin\Debug\Estudiantes.exe’ cargado. Símbolos cargados.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.String]

Tambien el foreach de la siguiente manera

Dictionary<string, string> datos = new Dictionary<string, string>();
datos.Add(“1”, “Mensaje uno”);
datos.Add(“2”, “Mensaje dos”);
foreach(var obj in datos) {
Console.WriteLine(obj.Key);
}

Resultado
’Estudiantes.exe’ (CLR v4.0.30319: DefaultDomain): ‘C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: DefaultDomain): ‘C:\Users\Sem-6-INGENIERIAINDU\source\repos\Estudiantes\Estudiantes\bin\Debug\Estudiantes.exe’ cargado. Símbolos cargados.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
‘Estudiantes.exe’ (CLR v4.0.30319: Estudiantes.exe): ‘C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll’ cargado. Se omitió la carga de símbolos. El módulo está optimizado y la opción del depurador ‘Sólo mi código’ está habilitada.
1
2

Al desactivar todo, tienes la posibilidad de controlar el código a voluntad.

Nota: solo no activo evaluaciones…; te da la posibilidad de hacer múltiples cosas

foreach (var val in obj.Value)
{
	if (imprEval || !(val is Evaluación)){
		if (val is Escuela)
			Console.WriteLine("Escuela: " + val);
		if (val is Alumno)
			Console.WriteLine("Alumno: " + val);
		if (val is Curso)
			Console.WriteLine("Curso: " + val);
		if (val is Asignatura)
			Console.WriteLine("Asignatura: " + val); 
	}
}
if(imprEval || !(val is Evaluacion)) {}

Si esta habilitada la evaluacion imprime todo, ya que al ser un OR al cumplirse la primera condición es suficiente, en caso que no esté habilitada las evaluaciones comprueba la segunda condición e imprime si el valor es distinto a Evaluación.

Un poco de mas código pero creo que un poco mas optimo

public void ImprimirDiccionario(Dictionary<LlaveDiccionario,IEnumerable<ObjetoEscuelaBase>> dic,bool imprimirevaluaciones = false)
        {
            foreach (var obj in dic)
            {
                if (obj.Key == LlaveDiccionario.Evaluacion)
                {
                    if (imprimirevaluaciones)
                    {
                        Util.Printer.Dibujar_Titulo(obj.Key.ToString());
                        foreach (var val in obj.Value)
                        {
                            Console.WriteLine(val);
                        }
                    }

                }
                else
                {
                    Util.Printer.Dibujar_Titulo(obj.Key.ToString());
                    foreach (var val in obj.Value)
                    {
                        Console.WriteLine(val);
                    }
                }          
            }            
        }

Excelente contenido, creo que se entro en una buena motivacion a como resolver el problema de imprimir o no las evaluaciones, Genial

Esta fue mi implementación

 public void ImprimirDiccionario(Dictionary<LlavesDiccionario, IEnumerable<ObjetoEscuelaBase>> dic, bool imprimirEval = false)
        {
            foreach (var obj in dic)
            {
                Printer.WriteTitle(obj.Key.ToString());

                foreach (var val in obj.Value)
                {
                   if (val is Evaluacion && imprimirEval)
                    {
                        Console.WriteLine(val);
                    } else if (val is Evaluacion && !imprimirEval)
                    {
                        continue;
                    } else
                    {
                        Console.WriteLine(val);
                    }
                }
            }
        }

se podría evaluar en una sola linea creo.

public static void PrintDcit(bool evaluation = false)
           {
                  var objects = SchoolObjects();
                  foreach (var obj in objects)
                  {
                      Utilities.WriteTitle(obj.Key.ToString());
                      foreach (var val in obj.Value)
                      {
                         if(!evaluation &&  val is Evaluation)
                          {
                              continue;
                          }

                           Console.WriteLine(val);
                      }
                  }
           }
public void ImprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dic, bool imprEval = false){
            foreach (var obj in dic)
            {
                Printer.WriteTitle(obj.Key.ToString());
                
                foreach (var val in obj.Value)
                {
                    if (imprEval || !(val is Evaluacion)){
                        if (val is Escuela)
                            Console.WriteLine("Escuela: "+val);
                        else if (val is Alumno)
                            Console.WriteLine("Alumno: "+val.Nombre);
                        else if (val is Curso)
                            Console.WriteLine("Curso: "+val.Nombre);
                        else if (val is Asignatura)
                            Console.WriteLine("Asignatura: "+val.Nombre);
                        else
                            Console.WriteLine("Evaluacion: "+val);                    
                    }
                }
            }
        }```

No entiendo porque analiza los valores individuales de todo el diccionario si podria analizar las llaves. A cada llave ya les fue asignado una lista de Evaluaciones, Escuela o alumnos respectivamente.

if ( ! (value is Evaluacion) || printEval )

Solucioné la impresión cuando no se quiere imprimir las evaluaciones de la siguiente manera:

public void ImprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dic, 
            bool ImprimirEval = false)
        {
            foreach (var obj in dic)
            {
                if(ImprimirEval && obj.Value is Evaluación)
                {
                    Printer.WriteTitle(obj.Key.ToString());
                    foreach (var valor in obj.Value)
                    {
                        Console.WriteLine(valor);
                    }
                }
                else
                {
                    if (obj.Key == LlaveDiccionario.Alumno || obj.Key == LlaveDiccionario.Asignatura || obj.Key == LlaveDiccionario.Curso || obj.Key == LlaveDiccionario.Escuela )
                    {
                        Printer.WriteTitle(obj.Key.ToString());
                        foreach (var valor in obj.Value)
                        {
                            Console.WriteLine(valor);
                        } 
                    }
                }
            }
        }```

Yo lo hice de esta forma

public void ImprimirDiccionario(Dictionary<LlavesDiccionario,IEnumerable<ObjetoEscuelaBase>> dic,
        bool imprimirEval=false)
        {
            foreach (var obj in dic)
            {
                Printer.DibujarTitulo(obj.Key.ToString());
                
                foreach (var val in obj.Value)
                {
                    if(imprimirEval && val is Evaluacion)
                      Console.WriteLine(val);
                    else if (!(val is Evaluacion))
                        Console.WriteLine(val);
                }
                
            }
        }

Esta es otra forma de hacerlo, fuera del loop de los valores de cada keyvalpair del diccionario, preguntamos la key y luego casteamos el value de IEnumerable<ParentEntity> a List<Alumno> SABIENDO que ese IEnumerable de ParentEntity viéndolo de la misma forma que la introducimos en el diccionario en los videos anteriores y de esa forma recuperamos la lista de alumnos que teníamos originalmente para trabajar con ella

                if (obj.Key == LLaveDiccionario.Alumno)
                {
                    List<Alumno> alumnosRec = (List<Alumno>)obj.Value;
                    foreach (Alumno alum in alumnosRec)
                    {
                        WriteLine(alum.Nombre);
                    }
                }

Recién a esta altura entendí el uso de los foreach anidados.

Mi implementación:

Yo lo hice de esta manera!

public void ImprimirDiccionario(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dictionary, bool imprimirEval = false)
        {

            foreach (var obj in dictionary)
            {
                Printer.WriteTitle(obj.Key.ToString());
                Console.WriteLine(obj);

                foreach (var val in obj.Value)
                {
                    if(val is Evaluación && imprimirEval)
                        Console.WriteLine(val);
                    else if(!(val is Evaluación))
                        Console.WriteLine(val);
                }
            }
        }```
private void PrintDictionary(Dictionary<DictionaryKey, IEnumerable<InitialCredential>> dictionary, bool printSub = true, bool printUser = true, bool printCourses = true)
        {
            foreach (var item in dictionary)
            {
                Printer.DTitle(item.Key.ToString());
                foreach (var item_2 in item.Value)
                {
                    if (printCourses && item_2 is Course)
                    {
                        Printer.DWrite($"{item_2.ToString()}");
                    }
                    else if (printSub && item_2 is Subject)
                    {
                        Printer.DWrite($"{item_2.ToString()}");
                    }
                    else if (printUser && item_2 is User)
                    {
                        Printer.DWrite($"{item_2.ToString()}");
                    }
                }
            }
        }

Genial.