public Employee2(string name, Employee2 boss = null)
 {
     this.Name = name;
     this.Boss = boss;
     if (this.Boss != null)
     {
         this.Boss.Subordinates.Add(this);
     }
 }
 public void SetBoss(Employee2 employee) => Boss = employee;
 public void RemoveSubordinate(Employee2 employee) => Subordinates.Remove(employee);
 public void AddSubordinate(Employee2 employee) => Subordinates.Add(employee);
        static void Advanced_1_RecursionWithCollections()
        {
            ConsoleTitle("SECTION: Recursion with Collections");

            Employee        e1        = new Employee("Big Cheese");
            Employee        e2        = new Employee("Monterey Jack", e1);
            Employee        e3        = new Employee("Cheddar", e1);
            List <Employee> employees = new List <Employee>();

            employees.Add(e1);
            employees.Add(e2);
            employees.Add(e3);

            Console.WriteLine("\n  Building JSON lists:");
            try
            {
                string brokenJson = JsonConvert.SerializeObject(employees, Formatting.Indented);
            }
            catch (JsonSerializationException)
            {
                Console.WriteLine("    Error: (Version 1) Self referencing loop detected! Serialization failed.");
            }
            JsonSerializerSettings ignoreLoopSettings = new JsonSerializerSettings
            {
                ContractResolver      = new PrivateSetResolver(),
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };
            string faultyJson = JsonConvert.SerializeObject(employees, Formatting.Indented, settings: ignoreLoopSettings);

            Console.WriteLine("    (Version 2) Ignore Loop, serialized but with lots of ugly repeating data");
            DrawJson(faultyJson, "faultyJson");             // confirm its contents -- everything will repeat a lot -- bad
            JsonSerializerSettings preserveReferenceSettings = new JsonSerializerSettings
            {
                ContractResolver           = new PrivateSetResolver(),
                PreserveReferencesHandling = PreserveReferencesHandling.Objects
            };
            string betterJson = JsonConvert.SerializeObject(employees, Formatting.Indented, settings: preserveReferenceSettings);

            Console.WriteLine("    (Version 3) Objects Preserve References, serialized and clean");
            DrawJson(betterJson, "betterJson");             // confirm its contents -- should look clean

            List <Employee> faultyList = (List <Employee>)JsonConvert.DeserializeObject <List <Employee> >(faultyJson, settings: preserveReferenceSettings);
            Employee        ne1a       = faultyList[0];
            Employee        ne2a       = faultyList[1];
            Employee        ne3a       = faultyList[2];

            List <Employee> betterList1 = (List <Employee>)JsonConvert.DeserializeObject <List <Employee> >(betterJson, settings: preserveReferenceSettings);
            Employee        ne1b        = betterList1[0];
            Employee        ne2b        = betterList1[1];
            Employee        ne3b        = betterList1[2];

            List <Employee2> betterList2 = (List <Employee2>)JsonConvert.DeserializeObject <List <Employee2> >(faultyJson, settings: preserveReferenceSettings);
            Employee2        ne1c        = betterList2[0];
            Employee2        ne2c        = betterList2[1];
            Employee2        ne3c        = betterList2[2];

            List <Employee2> bestList = (List <Employee2>)JsonConvert.DeserializeObject <List <Employee2> >(betterJson, settings: preserveReferenceSettings);
            Employee2        ne1d     = bestList[0];
            Employee2        ne2d     = bestList[1];
            Employee2        ne3d     = bestList[2];

            Console.WriteLine("\n  Original Data:");
            employees.ForEach(e => Console.WriteLine($"    {e}"));

            /*
             * // These all appear the same, but they're not!
             * Console.WriteLine("  Data v1:");
             * faultyList.ForEach(e => Console.WriteLine($"    {e}"));
             * Console.WriteLine("  Data v2:");
             * betterList1.ForEach(e => Console.WriteLine($"    {e}"));
             * Console.WriteLine("  Data v3:");
             * betterList2.ForEach(e => Console.WriteLine($"    {e}"));
             * Console.WriteLine("  Data v4:");
             * bestList.ForEach(e => Console.WriteLine($"    {e}"));
             */

            Console.WriteLine("\n  Expected Test Results:");
            AreTheseEqual(e1, e2.Boss);
            AreTheseEqual(e1.Subordinates[0], e2);
            AreTheseEqual(e1, e3.Boss);
            AreTheseEqual(e1.Subordinates[1], e3);
            Console.WriteLine("  Data v1 Tests (built from redundant collections):");
            AreTheseEqual(ne1a, ne2a.Boss);
            AreTheseEqual(ne1a.Subordinates[0], ne2a);
            AreTheseEqual(ne1a, ne3a.Boss);
            AreTheseEqual(ne1a.Subordinates[1], ne3a);
            Console.WriteLine("  Data v2 Tests (built from superior collection, but no default constructor):");
            AreTheseEqual(ne1b, ne2b.Boss);
            AreTheseEqual(ne1b.Subordinates[0], ne2b);
            AreTheseEqual(ne1b, ne3b.Boss);
            AreTheseEqual(ne1b.Subordinates[1], ne3b);
            Console.WriteLine("  Data v3 Tests (built from worse json, but with default constructor):");
            AreTheseEqual(ne1c, ne2c.Boss);
            AreTheseEqual(ne1c.Subordinates[0], ne2c);
            AreTheseEqual(ne1c, ne3c.Boss);
            AreTheseEqual(ne1c.Subordinates[1], ne3c);
            Console.WriteLine("  Data v4 Tests (built from sperior json, with default constructor):");
            AreTheseEqual(ne1d, ne2d.Boss);
            AreTheseEqual(ne1d.Subordinates[0], ne2d);
            AreTheseEqual(ne1d, ne3d.Boss);
            AreTheseEqual(ne1d.Subordinates[1], ne3d);
        }