static void Main(string [] args)
        {
            Employee aliceInEmployee = new Employee {
                Name         = "Alice",
                EmployeeCode = "AA123"
            };
            Person aliceInPerson = aliceInEmployee;

            // aliceInEmployee.WriteToConsole();
            // aliceInPerson.WriteToConsole();
            // WriteLine(aliceInEmployee.ToString());
            // WriteLine(aliceInPerson.ToString());

            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee e2 = (Employee)aliceInPerson;
                // do something with e2
            }

            Employee e1 = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            e1.EmployeeCode = "JJ001";
            e1.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{e1.Name} was hired on {e1.HireDate:dd/MM/yy}");

            try {
                e1.TimeTravel(new DateTime(1999, 12, 31));
                e1.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine($"{email1} is a valid email address: {StringExtensions.IsValidEmail(email1)}");
            WriteLine($"{email2} is a valid email address: {StringExtensions.IsValidEmail(email2)}");
        }
Example #2
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };

            // call instance method
            var baby1 = mary.ProcreateWith(harry);

            baby1.Name = "Gary";

            // call static method
            var baby2 = Person.Procreate(harry, jill);

            // call an operator
            var baby3 = harry * mary;

            WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            WriteLine($"{jill.Name} has {jill.Children.Count} children.");
            WriteLine(
                format: "{0}'s first child is named \"{1}\".",
                arg0: harry.Name,
                arg1: harry.Children[0].Name);

            WriteLine($"5! is {Person.Factorial(5)}");

            harry.Shout += Harry_Shout;
            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                }
            };

            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($"  {person.Name}");
            }

            WriteLine("Use Person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"  {person.Name}");
            }

            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"  {person.Name}");
            }

            var t1 = new Thing();

            t1.Data = 42;
            WriteLine($"Thing with an integer: {t1.Process(42)}");

            var t2 = new Thing();

            t2.Data = "apple";
            WriteLine($"Thing with a string: {t2.Process("apple")}");

            var gt1 = new GenericThing <int>();

            gt1.Data = 42;
            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");

            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            string number1 = "4";

            WriteLine("{0} squared is {1}",
                      arg0: number1,
                      arg1: Squarer.Square <string>(number1));

            byte number2 = 3;

            WriteLine("{0} squared is {1}",
                      arg0: number2,
                      arg1: Squarer.Square(number2));

            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine(
                $"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");

            Employee john = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 27)
            };

            john.WriteToConsole();

            john.EmployeeCode = "33001";
            john.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{john.Name} was hired on {john.HireDate:MM/dd/yy}");

            WriteLine(john.ToString());

            Employee aliceInEmployee = new Employee
            {
                Name = "Alice", EmployeeCode = "AA123"
            };

            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            WriteLine(aliceInEmployee.ToString());
            WriteLine(aliceInPerson.ToString());

            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee explicitAlice = (Employee)aliceInPerson;
                // safely do something with explicitAlice
            }

            Employee aliceAsEmployee = aliceInPerson as Employee;

            if (aliceAsEmployee != null)
            {
                WriteLine($"{nameof(aliceInPerson)} AS an Employee");
                // do somethign with aliceAsEmployee
            }

            try
            {
                john.TimeTravel(new DateTime(1999, 12, 31));
                john.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email1,
                arg1: StringExtensions.IsValidEmail(email1));

            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email2,
                arg1: StringExtensions.IsValidEmail(email2));

            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email1,
                arg1: email1.IsValidEmail());

            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email2,
                arg1: email2.IsValidEmail());
        }
Example #3
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };

            //call instance method
            var baby1 = mary.ProcreateWith(harry);

            //call static method
            var baby2 = Person.Procreate(harry, jill);

            //call an operator
            var baby3 = harry * mary;

            // WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            // WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            // WriteLine($"{jill.Name} has {jill.Children.Count} children.");

            // WriteLine($"{harry.Name}'s first child is namedd \"{harry.Children[0].Name}\".");

            // WriteLine($"5! is {Person.Factorial(5)}");

            //p.189 add a statement to assign the method to the delegate field
            // harry.Shout += Harry_Shout;
            //add statements to call the Poke method four times
            // harry.Poke();
            // harry.Poke();
            // harry.Poke();
            // harry.Poke();

            //p.192 add statements that create an array of Person instances and writes the items to the console, and then attempts to sort the array and writes the items to the console again.
            // Person[] people =
            // {
            //     new Person {Name = "Simon"},
            //     new Person {Name = "Jenny"},
            //     new Person {Name = "Adam"},
            //     new Person {Name = "Richard"}
            // };
            // WriteLine("Initial list of people:");
            // foreach (var person in people)
            // {
            //     WriteLine($"{person.Name}");
            // }
            // WriteLine($"Use Person's IComparable implementation to sort:");
            // Array.Sort(people);
            // foreach (var person in people)
            // {
            //     WriteLine($"{person.Name}");
            // }

            //add statements to sort the array using this alternative implementation p.195
            // WriteLine("Use PersonComparer's IComparer implementation to sort: ");
            // Array.Sort(people, new PersonComparer());
            // foreach (var person in people)
            // {
            //     WriteLine($"{person.Name}");
            // }

            //p.199-201
            // var t1 = new Thing();
            // t1.Data = 42;
            // WriteLine($"Thing with an integer: {t1.Process(42)}");

            // var t2 = new Thing();
            // t2.Data = "apple";
            // WriteLine($"Thing with a string: {t2.Process("apple")}");

            // var gt1 = new GenericThing<int>();
            // gt1.Data = 42;
            // WriteLine($"GenericThing with an integer: {gt1.Process(42)}");

            // var gt2 = new GenericThing<string>();
            // gt2.Data = "apple";
            // WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            //p.202
            // string number1 = "4";
            // byte number2 = 3;
            // WriteLine($"{number1} squared is {Squarer.Square<string>(number1)}");
            // WriteLine($"{number2} squared is {Squarer.Square(number2)}");

            //p.204
            // var dv1 = new DisplacementVector(3,5);
            // var dv2 = new DisplacementVector(-2,7);
            // var dv3 = dv1 + dv2;
            // WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");

            //p.208 create an instance of the Employee class which inherits from the Person class
            Employee john = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            // john.WriteToConsole();

            //p.208-209 extending classes and hiding members
            john.EmployeeCode = "JJ001";
            john.HireDate     = new DateTime(2014, 11, 23);
            // WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yy}");

            //p.210 Overriding members. write value of the john variable to the console as a string
            // WriteLine(john.ToString());

            //p.212 create new employee and call WriteToConsole and ToString methods from the Person and Employee classes
            Employee aliceInEmployee = new Employee
            {
                Name         = "Alice",
                EmployeeCode = "AA123"
            };

            Person aliceInPerson = aliceInEmployee;

            // aliceInEmployee.WriteToConsole();
            // aliceInPerson.WriteToConsole();

            // WriteLine(aliceInEmployee.ToString());
            // WriteLine(aliceInPerson.ToString());

            //p.214-215 Explicit casting and avoiding casting exceptions
            if (aliceInPerson is Employee)
            {
                // WriteLine($"{nameof(aliceInPerson)} IS an Employee");

                Employee explicitAlice = (Employee)aliceInPerson;
                //safely do something with explicitAlice
            }

            Employee aliceAsEmployee = aliceInPerson as Employee;

            if (aliceAsEmployee != null)
            {
                // WriteLine($"{nameof(aliceInPerson)} AS an Employee");
                //do something with aliceAsEmployee
            }

            //p.217
            // try
            // {
            //     john.TimeTravel(new DateTime(1999, 12, 31));
            //     john.TimeTravel(new DateTime(1950, 12, 25));
            // }
            // catch (PersonException ex)
            // {
            //     WriteLine(ex.Message);
            // }

            //p.218 add statements to validate two examples of email addresses
            string email1 = "*****@*****.**";
            string email2 = "*****@*****.**";

            WriteLine($"{email1} is a valid e-mail address: {StringExtensions.IsValidEmail(email1)}");

            WriteLine($"{email2} is a valid e-mail address: {StringExtensions.IsValidEmail(email2)}");
        }
Example #4
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };

            // call instance method
            var baby1 = mary.ProcreateWith(harry);

            // call static method
            var baby2 = Person.Procreate(harry, jill);

            // call an operator
            var baby3 = harry * mary;

            WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            WriteLine($"{jill.Name} has {jill.Children.Count} children.");
            WriteLine($"{mary.Name}'s first child is named \"{mary.Children[0].Name}\".");

            WriteLine($"5! is {Person.Factorial(5)}");

            harry.Shout += Harry_Shout;

            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                }
            };

            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("Use Person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            var t = new Thing();

            t.Data = 42;
            WriteLine($"Thing: {t.Process("42")}");

            var gt = new GenericThing <int>();

            gt.Data = 42;
            WriteLine($"GenericThing: {gt.Process("42")}");

            string number1 = "42";

            WriteLine($"{number1} squared is {Squarer.Square<string>(number1)}");

            byte number2 = 13;

            WriteLine($"{number2} squared is {Squarer.Square<byte>(number2)}");

            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");

            Employee e1 = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            e1.WriteToConsole();

            e1.EmployeeCode = "JJ001";
            e1.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{e1.Name} was hired on {e1.HireDate:dd/MM/yy}");

            WriteLine(e1.ToString());

            Employee aliceInEmployee = new Employee
            {
                Name = "Alice", EmployeeCode = "AA123"
            };
            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            WriteLine(aliceInEmployee.ToString());
            WriteLine(aliceInPerson.ToString());

            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee e2 = (Employee)aliceInPerson;
                // do something with e2
            }

            Employee e3 = aliceInPerson as Employee;

            if (e3 != null)
            {
                WriteLine($"{nameof(aliceInPerson)} AS an Employee");
                // do something with e3
            }

            try
            {
                e1.TimeTravel(new DateTime(1999, 12, 31));
                e1.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine($"{email1} is a valid e-mail address: {StringExtensions.IsValidEmail(email1)}.");
            WriteLine($"{email2} is a valid e-mail address: {StringExtensions.IsValidEmail(email2)}.");

            WriteLine($"{email1} is a valid e-mail address: {email1.IsValidEmail()}.");
            WriteLine($"{email2} is a valid e-mail address: {email2.IsValidEmail()}.");
        }
Example #5
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };
            //call instance method
            var baby1 = mary.ProcreateWith(harry);
            // call static method
            var baby2 = Person.Procreate(harry, jill);

            WriteLine($"{harry.Name} has {harry.Children.Count} children");
            WriteLine($"{mary.Name} has {mary.Children.Count} children");
            WriteLine($"{jill.Name} has {jill.Children.Count} children");
            WriteLine(format: "{0}'s first child is named \"{1}\".", arg0: harry.Name, arg1: harry.Children[0].Name);
            // call an operator
            var baby3 = harry * mary;

            // call method with internal local function
            WriteLine($"5! is {Person.Factorial(5)}");
            harry.Shout += Harry_Shout;
            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            harry.Start += Receive_Call;
            harry.ReceiveCall();
            harry.ReceiveCall();
            harry.ReceiveCall();
            harry.ReceiveCall();
            // Interfaces IComparable (allows arrays and collection to be sorted)
            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                }
            };
            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }
            WriteLine("Use person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            // Compare Names using IComparer Interfaces
            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            // Generics
            var t1 = new Thing();

            t1.Data = 42;
            WriteLine($"Thing with an integer: {t1.Process(42)}");
            var t2 = new Thing();

            t2.Data = "apple";
            WriteLine($"Thing with a string: {t2.Process("apple")}");

            var gt1 = new GenericThing <int>();

            gt1.Data = 42;
            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");
            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            // Working with generic methods
            string number1 = "4";

            WriteLine("{0} squared is {1}", arg0: number1, arg1: Squarer.Square <string>(number1));
            byte number2 = 3;

            WriteLine("{0} squared is {1}", arg0: number2, arg1: Squarer.Square(number2));

            // Memory Management
            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");


            // Inheriting from classes
            Employee john = new Employee {
                Name = "John Jones", DateOfBirth = new DateTime(1990, 7, 28)
            };

            john.WriteToConsole();
            john.EmployeeCode = "JJ001";
            john.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yy}");
            WriteLine(john.ToString());

            // Overriding methods
            Employee aliceInEmployee = new Employee
            {
                Name         = "Alice",
                EmployeeCode = "AA123"
            };
            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            WriteLine(aliceInEmployee.ToString());
            WriteLine(aliceInPerson.ToString());

            // Casting
            // Not Safe an Invalid Cast exception could appear
            // Employee explicitAlice = (Employee)aliceInPerson;
            // is keyword
            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");

                Employee explicitAlice = (Employee)aliceInPerson;
                // safetily do something with explicitAlice
            }

            // as keyword
            Employee aliceAsEmployee = aliceInPerson as Employee;

            if (aliceAsEmployee != null)
            {
                WriteLine($"{nameof(aliceInPerson)} AS an employee");
                // do something with aliceAsEmployee
            }

            // Custom Exception
            try
            {
                john.TimeTravel(new DateTime(1999, 12, 31));
                john.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            // Extension Methods

            string email1 = "*****@*****.**";

            email1.ExtensionParameter("Test");
            string email2 = "ian&test.com";

            WriteLine("{0} is a valid e-mail address: {1}", arg0: email1, arg1: StringExtensions.IsValidEmail(email1));
            WriteLine("{0} is a valid e-mail address: {1}", arg0: email2, arg1: StringExtensions.IsValidEmail(email2));

            // statements to use extension methods
            WriteLine("{0} is a valid e-mail address: {1}", arg0: email1, arg1: email1.IsValidEmail());
            WriteLine("{0} is a valid e-mail address: {1}", arg0: email1, arg1: email2.IsValidEmail());
        }
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };

            // call instance method
            var baby1 = mary.ProcreateWith(harry);

            // call static method
            var baby2 = Person.Procreate(harry, jill);

            // call an operator
            var baby3 = harry * mary;

            WriteLine($"{harry.Name} has {harry.Children.Count} children");
            WriteLine($"{mary.Name} has {mary.Children.Count} children");
            WriteLine($"{jill.Name} has {jill.Children.Count} children");

            WriteLine(
                format: "{0}'s first child is named \"{1}\".",
                arg0: harry.Name,
                arg1: harry.Children[0].Name
                );

            // calling the local function
            WriteLine($"5! is {Person.Factorial(5)}");

            harry.Shout += Harry_Shout;
            int count = 0;

            do
            {
                harry.Poke();
                count++;
            }while (count < 4);

            // Comparing objects when sorting

            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                },
            };

            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("User Person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            var t1 = new Thing();

            t1.Data = 42;
            WriteLine($"Thing with integer: {t1.Process(42)}");

            var t2 = new Thing();

            t2.Data = "apple";
            WriteLine($"Thing with a string {t2.Process("apple")}");

            var gt1 = new GenericThing <int>();

            gt1.Data = 42;
            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");

            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            string number1 = "4";

            WriteLine("{0} squared is {1}", arg0: number1, arg1: Squarer.Square <string>(number1));

            byte number2 = 3;

            WriteLine("{0} squared is {1}", arg0: number1, arg1: Squarer.Square(number2));

            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");

            Employee john = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            john.WriteToConsole();

            john.HireDate     = new DateTime(2014, 11, 23);
            john.EmployeeCode = "JJ001";
            WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yy}");

            WriteLine(john.ToString());

            Employee aliceInEmployee = new Employee {
                Name = "Alice", EmployeeCode = "AA123", DateOfBirth = new DateTime(1970, 12, 12)
            };
            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            WriteLine(aliceInEmployee.ToString());
            WriteLine(aliceInPerson.ToString());

            /*
             * When a method is overridden with virtual and override, the compiler is smart
             * enough to know that although the variable is declared as a Person class, the object
             * itself is an Employee class and, therefore, the Employee implementation of ToString
             * is called.
             */

            // Explicit casting (safely)
            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee explicitAlice = (Employee)aliceInPerson;
            }
            // can also use `as` keyword and check for null
            Employee aliceAsEmployee = aliceInPerson as Employee;

            if (aliceAsEmployee != null)
            {
                // we can do something with aliceAsEmployee
                WriteLine($"{nameof(aliceInPerson)} AS an Employee");
            }

            try
            {
                aliceInEmployee.TimeTravel(new DateTime(1999, 12, 31));
                aliceInEmployee.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email1,
                arg1: StringExtensions.IsValidEmail(email1)
                );
            WriteLine(
                "{0} is a valid e-mail address: {1}",
                arg0: email2,
                arg1: StringExtensions.IsValidEmail(email2)
                );
        }
Example #7
0
        static void Main(string[] args)
        {
            // Test Casting
            // Person(base) casting to Employee(sub Class) is not ok
            int a = 100;

            WriteLine("INT type:{0}", a.GetType().Name);
            Person edwardInPerson = new Person {
                Name = "Edward"
            };

            if (edwardInPerson is Employee)
            {
                Employee edwardInEmployee = (Employee)edwardInPerson;
            }
            else
            {
                WriteLine("EdwardInPerson is Not Employee, is {0}", edwardInPerson.GetType());
            }
            Employee YvonneInEmployee = new Employee {
                Name = "Alice", EmployeeCode = "AA123"
            };

            if (YvonneInEmployee is Employee)
            {
                Person YvonneInPerson = YvonneInEmployee; // Employee casting to Person is ok
                WriteLine("YvonneInPerson is {0}", YvonneInPerson.GetType());
                WriteLine("YvonneInEmployee is {0}", YvonneInEmployee.GetType());
                if (YvonneInPerson is Employee)
                {
                    WriteLine("YvonneInPerson is actually Employee!");
                    Employee explicitYvonneInPersonToEmployee = (Employee)YvonneInPerson;
                }
            }
            else
            {
                WriteLine("YvonneInEmployee is Not Employee, is {0}", edwardInPerson.ToString());
            }


            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };
            var may = new Person {
                Name = "May"
            };
            // call instance method
            var baby1 = mary.ProcreateWith(harry);

            baby1.Name = "Gary";
            // call static method
            var baby2 = Person.Procreate(harry, jill);

            WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            WriteLine($"{jill.Name} has {jill.Children.Count} children.");
            for (int i = 0; i < harry.Children.Count; i++)
            {
                WriteLine(
                    format: "{0}'s {1} child is named \"{2}\".",
                    harry.Name, i, harry.Children[i].Name);
            }
            var baby3 = may * jill;

            WriteLine($"{may.Name} has {may.Children.Count} children.");
            for (int i = 0; i < jill.Children.Count; i++)
            {
                WriteLine(
                    format: "{0}'s {1} child is named \"{2}\".",
                    jill.Name, i, jill.Children[i].Name);
            }
            WriteLine($"Person Factorial 5: {may.Factorial(5)}");
            // event handler: assign Event Listener
            // When assigning a method to a delegate field, you should not use the simple assignment operator as we did in the preceding example, and as shown in the following code:
            // harry.Shout = Harry_Shout;
            //  If the Shout delegate field was already referencing one or more methods, by assigning a method, it would replace all the others. With delegates that are used for events
            // we usuallywant to make sure that a programmer only ever uses either the += operator or the -= operator to assign and remove methods:
            harry.Shout += Harry_Shout;
            harry.Shout += Harry_Shout;
            harry.Shout += Harry_Shout;
            harry.Shout -= Harry_Shout;
            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();
            // -----------------------------------
            // test coommon interface[Icomparable/Icompare] by Array.Sort
            // -----------------------------------
            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                }
            };
            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($" {person.Name}");
            }
            WriteLine("Use Person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($" {person.Name}");
            }
            for (int idx = 0; idx < people.Length; idx++)
            {
                WriteLine($" {people[idx].Name}");
            }
            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($" {person.Name}");
            }
            // Defining interfaces with default implementations
            var dvdplayer = new DvdPlayer();

            dvdplayer.Play();
            dvdplayer.Pause();
            dvdplayer.Stop();
            dvdplayer.Error();
            dvdplayer.Error2();
            var odvdplayer = new DvdPlayerOld();

            odvdplayer.Play();
            odvdplayer.Pause();
            odvdplayer.Stop();
            odvdplayer.Error();
            // ----------------------------
            // test generics Type:
            // ----------------------------
            // Note the following:
            // • When instantiating an instance of a generic type, the developer must pass a
            // type parameter. In this example, we pass int as the type parameter for gt1 and
            // string as the type parameter for gt2, so wherever T appears in the GenericThing
            // class, it is replaced with int and string.
            // • When setting the Data field and passing the input parameter, the compiler
            // enforces the use of an int value, such as 42, for
            // ----------------------------
            var gt1 = new GenericThing <int> {
                Data = 42
            };

            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");
            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            string number1 = "4.5";

            WriteLine("{0} squared is {1}",
                      arg0: number1,
                      arg1: Squarer.Square <string>(number1));
            byte number2 = 3;

            WriteLine("{0} squared is {1}",
                      arg0: number2,
                      arg1: Squarer.Square(number2));
            // ----------------------------------
            // test struct
            // ----------------------------------
            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X},{dv3.Y})");
            // ----------------------------------
            // test  Inheriting from classes
            // ----------------------------------
            Employee john = new Employee {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            WriteLine(format: "employee {0}'s birthdate is {1:dddd,dd/MM/yy}", john.Name, john.DateOfBirth);
            john.EmployeeCode = "JJ001";
            john.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yy}");
            john.WriteToConsole();

            WriteLine("==============================");
            WriteLine("Testing polymorphic");
            WriteLine("==============================");
            Person   pMike           = new Person();
            Employee aliceInEmployee = new Employee {
                Name = "Alice", EmployeeCode = "AA123"
            };

            // implicit casting
            Person aliceInPerson = aliceInEmployee;

            // When a method is hidden with new, the compiler is not smart enough to know that the object is an Employee, so it calls the WriteToConsole method in Person.
            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            // When a method is overridden with virtual and override, the compiler is smart enough to know that although the variable is declared as a Person class, the object itself is an Employee class and, therefore, the Employee implementation of ToString is called.
            WriteLine($"Person ToString():{pMike.ToString()}");
            WriteLine($"aliceInEmployee ToString():{aliceInEmployee.ToString()}");
            WriteLine($"aliceInPerson ToString():{aliceInPerson.ToString()}");
            WriteLine("==============================");
            WriteLine("Testing casting");
            WriteLine("==============================");
            // checking type before casting using "is"
            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee explicitAlice = (Employee)aliceInPerson;
                explicitAlice.WriteToConsole();
            }
            else
            {
                WriteLine($"{nameof(pMike)} is NOT an Employee");
            }
            // checking type before casting  using "is"
            if (pMike is Employee)
            {
                WriteLine($"{nameof(pMike)} IS an Employee");
                Employee explicitMike = (Employee)pMike;
                explicitMike.WriteToConsole();
            }
            else
            {
                WriteLine($"{nameof(pMike)} is NOT an Employee");
            }
            // checking type before casting  using "as"
            WriteLine("*** checking type before casting  using 'is'");

            Employee aliceAsEmployee = aliceInPerson as Employee;

            if (aliceAsEmployee != null)
            {
                WriteLine($"{nameof(aliceInPerson)} AS an Employee");
            }
            else
            {
                WriteLine($"{nameof(aliceInPerson)} NOT as an Employee");
            }
            // checking type before casting  using "as"
            WriteLine("*** checking type before casting  using 'as'");
            Employee mikeAsEmployee = pMike as Employee;

            if (mikeAsEmployee != null)
            {
                WriteLine($"{nameof(pMike)} AS an Employee");
            }
            else
            {
                WriteLine($"{nameof(pMike)} NOT as an Employee");
            }
            try
            {
                john.TimeTravel(new DateTime(1999, 12, 31));
                john.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }
            try
            {
                john.TimeTravel2(new DateTime(1999, 12, 31));
                john.TimeTravel2(new DateTime(1950, 12, 25));
            }
            catch (Exception ex)
            {
                WriteLine(ex.Message);
            }
            WriteLine("===================================");
            WriteLine("Testing Extending types when you can't inherit");
            WriteLine("===================================");
            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine("*** Using static methods to reuse functionality");
            WriteLine(format: "{0} is a valid e-mail address: {1}",
                      arg0: email1,
                      arg1: StringExtensions.IsValidEmail(email1));
            WriteLine(format: "{0} is a valid e-mail address: {1}",
                      arg0: email2,
                      arg1: StringExtensions.IsValidEmail(email2));
            WriteLine("*** Using extension methods to reuse functionality");
            WriteLine(format: "{0} is a valid e-mail address: {1}",
                      arg0: email1,
                      arg1: email1.IsValidEmail());
            WriteLine(format: "{0} is a valid e-mail address: {1}",
                      arg0: email2,
                      arg1: email2.IsValidEmail());
        }
Example #8
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };

            // call the instance method
            var baby1 = mary.ProcreateWith(harry);

            // call the static method
            var baby2 = Person.Procreate(harry, jill);

            // call an operator
            var baby3 = harry * mary;

            WriteLine($"{harry.Name} has {harry.Children.Count} children. ");
            WriteLine($"{mary.Name} has {mary.Children.Count} children. ");
            WriteLine($"{jill.Name} has {jill.Children.Count} children. ");

            WriteLine(
                format: "{0}'s first child is named \"{1}\".",
                arg0: harry.Name,
                arg1: harry.Children[0].Name
                );

            WriteLine($"5! is {Person.Factorial(5)}");

            // defining and hanlding delegates
            harry.Shout = Harry_Shout;
            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                },
            };
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }
            // Use Person's IComparable implmentation to sort:
            WriteLine("Use Person's IComparable implementatjoin to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            // working with generic types
            // pre C# 2.0
            var t1 = new Thing();

            t1.Data = 42;
            WriteLine($"Thing with an integer: {t1.Process(42)}");

            var t2 = new Thing();

            t2.Data = "apple";
            WriteLine($"Thing with a string: {t2.Process("apple")}");

            // C# 2.0
            var gt1 = new GenericThing <int>();

            gt1.Data = 42;
            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");

            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with a string: {gt2.Process("apple")}");

            // working with generic methods
            string number1 = "4";

            WriteLine(
                format: "{0} squared is {1}",
                arg0: number1,
                arg1: Squarer.Square <string>(number1)
                );

            byte number2 = 3;

            WriteLine(
                format: "{0} squared is {1}",
                arg0: number2,
                arg1: Squarer.Square <byte>(number2)
                );

            // working with struct types
            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})");

            // Inheriting from classes
            Employee john = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            john.EmployeeCode = "JJ001";
            john.HireDate     = new DateTime(2014, 11, 23);
            john.WriteToConsole();
            WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yyyy}");
            WriteLine(john.ToString());

            // understanding polymorphism
            Employee aliceInEmployee = new Employee
            {
                Name         = "Alice",
                EmployeeCode = "AA123"
            };
            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();                 // Employee.WriteToConsole()
            aliceInPerson.WriteToConsole();                   // Person.WriteToConsole()
            WriteLine(aliceInEmployee.ToString());            // Employee ToString()
            WriteLine(aliceInPerson.ToString());              // Employee override ToString()
            Employee explicitAlice = (Employee)aliceInPerson; // same as below

            //Employee aliceAsEmployee = aliceInPerson as Employee; // same as above
            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
            }

            // inheriting expceptions
            try
            {
                john.TimeTravel(new DateTime(1999, 12, 31));
                john.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            // using static methods to reuse functionality
            // public bool IsValidEmail(this string input)
            //public static bool IsValidEmail(this string input)
            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine(
                format: "{0} is a valid e-mail address: {1}",
                arg0: email1,
                arg1: StringExtensions.IsValidEmail(email1)
                );
            WriteLine(
                format: "{0} is a valid e-mail address: {1}",
                arg0: email2,
                arg1: StringExtensions.IsValidEmail(email2)
                );
            // using extension methods to reuse functionality (see LINQ for powerful uses of extensions)
            //public static bool IsValidEmail(this string input)
            WriteLine(
                format: "{0} is a valid e-mail address: {1}",
                arg0: email1,
                arg1: email1.IsValidEmail()
                );
            WriteLine(
                format: "{0} is a valid e-mail address: {1}",
                arg0: email2,
                arg1: email2.IsValidEmail()
                );
        }
Example #9
0
        static void Main(string[] args)
        {
            var harry = new Person {
                Name = "Harry"
            };
            var mary = new Person {
                Name = "Mary"
            };
            var jill = new Person {
                Name = "Jill"
            };
            // метод вызова экземпляра
            var baby1 = mary.ProcreateWith(harry);
            // метод статического вызова
            var baby2 = Person.Procreate(harry, jill);
            // вызов оператора
            var baby3 = harry * mary;

            WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            WriteLine($"{jill.Name} has {jill.Children.Count} children.");
            WriteLine($"{mary.Name}'s first child is named \"{mary.Children[0].Name}\".");

            WriteLine($"5! is {Person.Factorial(5)}");

            //TODO FAILED DELEGATE
            var p1 = new Person {
                Name = "Crybaby"
            };
            var d       = new DelegateWithMatchingSignature(p1.MethodIWantToCall);
            int answer2 = d("Frog");

            // Crate an instance of the delegate, pointing to the logging function.
            // This delegate will then be passed to the Process() function.
            LogHandler myLogger = new LogHandler(Logger);

            Person.Process(myLogger);

            //TODO EVENT HANDLER
            harry.Shout += Harry_Shout;
            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            // INTERFACES
            Person[] people =
            {
                new Person {
                    Name = "Simon"
                },
                new Person {
                    Name = "Jenny"
                },
                new Person {
                    Name = "Adam"
                },
                new Person {
                    Name = "Richard"
                }
            };

            WriteLine("Initial list of people:");
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            WriteLine("Use Person's IComparable implementation to sort:");
            Array.Sort(people);
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            //TODO Arrat.Sort принимать компаратор вторым параметром
            // который реализует интерфейс IComparer?
            WriteLine("Use PersonComparer's IComparer implementation to sort:");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                WriteLine($"{person.Name}");
            }

            //TODO Создание универсальных типов
            var t = new Thing();

            t.Data = 42;
            WriteLine($"Thing: {t.Process("42")}");

            var gt = new GenericThing <int>();

            gt.Data = 42;
            WriteLine($"GenericThing: {gt.Process("42")}");

            //TODO Создание универсального метода
            string number1 = "4";

            WriteLine($"{number1} squared is {Squarer.Square<string>(number1)}");
            byte number2 = 3;

            WriteLine($"{number2} squared is {Squarer.Square<byte>(number2)}");

            //TODO Определение структур
            var dv1 = new DisplacementVector(3, 5);
            var dv2 = new DisplacementVector(-2, 7);
            var dv3 = dv1 + dv2;

            WriteLine($"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X},{dv3.Y})");

            // Наследование классов
            Employee e1 = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            e1.WriteToConsole();

            e1.EmployeeCode = "JJ001";
            e1.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{e1.Name} was hired on {e1.HireDate:dd/MM/yy}");

            WriteLine(e1.ToString());

            //TODO Что происходит на при определении Person aliceInPerson?
            //TODO а если object aliceInEmployee = new Employee { Name = "Alice"};
            Employee aliceInEmployee = new Employee {
                Name = "Alice", EmployeeCode = "AA123"
            };
            Person aliceInPerson = aliceInEmployee;

            aliceInEmployee.WriteToConsole();
            aliceInPerson.WriteToConsole();
            WriteLine(aliceInEmployee.ToString());
            WriteLine(aliceInPerson.ToString());

            //Явное приведение
            if (aliceInPerson is Employee)
            {
                WriteLine($"{nameof(aliceInPerson)} IS an Employee");
                Employee e2 = (Employee)aliceInPerson;
                // действия с e2
            }

            Employee e3 = aliceInPerson as Employee;

            if (e3 != null)
            {
                WriteLine($"{nameof(aliceInPerson)} AS an Employee");
                // действия с e3
            }

            //Наследование исключений
            try
            {
                e1.TimeTravel(new DateTime(1999, 12, 31));
                e1.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }

            //Расширение типов при невозможности наследования
            string email1 = "*****@*****.**";
            string email2 = "ian&test.com";

            WriteLine($"{email1} is a valid e-mail address: {StringExtensions.IsValidEmail(email1)}.");
            WriteLine($"{email2} is a valid e-mail address: {StringExtensions.IsValidEmail(email2)}.");

            //Extension methods
            WriteLine($"{email1} is a valid e-mail address: {email1.IsValidEmail()}.");
            WriteLine($"{email2} is a valid e-mail address: {email2.IsValidEmail()}.");
        }
        static void Main(string[] args)
        {
            var harry = new Person("Harry");
            var mary  = new Person("Mary");
            var jill  = new Person("Jill");

            var baby1 = mary.ProcreateWith(harry);
            var baby2 = Person.Procreate(harry, jill);
            // multiply operator overloaded with the Person class:
            var baby3 = harry * mary;

            WriteLine($"{harry.Name} has {harry.Children.Count} children.");
            WriteLine($"{mary.Name} has {mary.Children.Count} children.");
            WriteLine($"{jill.Name} has {jill.Children.Count} children.");
            WriteLine(
                format: "{0}'s first child is called {1}",
                arg0: harry.Name,
                arg1: harry.Children[0].Name
                );

            WriteLine($"5! is {Person.Factorial(5)}");


            // assign the method defined in this program to the delegate field
            // note: delegates are multicast so can assign multiple delegates to a single delegate field although no control as to order called
            // so could have used += operator instead of just the = assignment operator (book page 189)
            harry.Shout += Harry_Shout;

            harry.Poke();
            harry.Poke();
            harry.Poke();
            harry.Poke();

            // BOOK: page 192 INTERFACES
            Person[] people =
            {
                new Person("Simon"),
                new Person("Jenny"),
                new Person("Adam"),
                new Person("Richard")
            };

            WriteLine("People unsorted: ");
            foreach (var person in people)
            {
                Write($"{person.Name} ");
            }
            WriteLine();

            WriteLine("People sorted - uses IComparable implementation to sort: ");
            Array.Sort(people);
            foreach (var person in people)
            {
                Write($"{person.Name} ");
            }
            WriteLine();


            WriteLine("People sorted - uses PersonComparer (implements IComparer) class sort: ");
            Array.Sort(people, new PersonComparer());
            foreach (var person in people)
            {
                Write($"{person.Name} ");
            }
            WriteLine();

            // BOOK: page 198 making types safely reusable with GENERICS
            var t1 = new Thing();

            t1.Data = 42;
            WriteLine($"Thing with an integer: {t1.Process(42)}");

            var t2 = new Thing();

            t2.Data = "apple";
            WriteLine($"Thing with an string: {t2.Process("apple")}");

            // on instantiating instance of generic type, must pass a type parameter
            var gt1 = new GenericThing <int>();

            gt1.Data = 42;
            WriteLine($"GenericThing with an integer: {gt1.Process(42)}");

            var gt2 = new GenericThing <string>();

            gt2.Data = "apple";
            WriteLine($"GenericThing with an string: {gt2.Process("apple")}");

            string number1 = "4";

            WriteLine("{0} squared is {1}",
                      arg0: number1,
                      arg1: Squarer.Square <string>(number1));

            byte number2 = 3;

            WriteLine("{0} squared is {1}",
                      arg0: number1,
                      arg1: Squarer.Square <byte>(number2));

            var vector1 = new DisplacementVector(3, 4);
            var vector2 = new DisplacementVector(-2, 1);
            var vector3 = vector1 + vector2;

            WriteLine($"vector3: {vector3.X}, {vector3.Y}");

            Employee john = new Employee
            {
                Name        = "John Jones",
                DateOfBirth = new DateTime(1990, 7, 28)
            };

            john.WriteToConsole();
            john.EmployeeCode = "JJ001";
            john.HireDate     = new DateTime(2014, 11, 23);
            WriteLine($"{john.Name} was hired on {john.HireDate:dd/MM/yy} with code {john.EmployeeCode}");

            WriteLine(john.ToString());
            WriteLine();

            // BOOK: page 212 Understanding polymorphism ---------------------------------------------------------------------

            // implicit casting section ****
            // an instance of a derived type (Employee) can be stored in a variable of the base type (Person) - IMPLICIT CASTING
            Employee aliceEmployee = new Employee {
                Name = "Alice", EmployeeCode = "AA123"
            };
            Person alicePerson = aliceEmployee;  // IMPLICIT casting

            WriteLine("Understanding Polymorphism section: ");
            WriteLine("alicePerson has just been assigned to aliceEmployee i.e. alicePerson = aliceEmployee");
            WriteLine();
            WriteLine("Now calling aliceEmployee.WriteToConsole(), then alicePerson.WriteToConsole()");
            aliceEmployee.WriteToConsole();                                             // Employee.WriteToConsole(): Alice was born on 01/01/01 and hired on 01/01/01
            alicePerson.WriteToConsole();                                               // Person.WriteToConsole(): Alice was born on a Monday
            WriteLine("Calling aliceEmployee.ToString(): " + aliceEmployee.ToString()); // Employee.ToString(): Alice's code is AA123
            WriteLine("Calling alicePerson.ToString(): " + alicePerson.ToString());     // Employee.ToString(): Alice's code is AA123

            // explicit casting section - and avoiding Casting Exceptions two options: use 'is' or 'as' keywords ****

            // use keyword 'is'
            if (alicePerson is Employee)
            {
                WriteLine($"{nameof(alicePerson)} IS an Employee - because of earlier assignment: alicePerson = aliceEmployee");
                // safe to cast
                Employee explicitAlice = (Employee)alicePerson;
            }

            Employee aliceAsEmployee = alicePerson as Employee; // keyword 'as' used to explicity cast --> need to check for null though

            if (aliceAsEmployee != null)
            {
                WriteLine($"{nameof(alicePerson)} AS an Employee - because of earlier assignment: Employee aliceAsEmployee = alicePerson as Employee");
            }



            // BOOK: page 216 Inheriting exceptions  ---------------------------------------------------------------------
            try
            {
                john.TimeTravel(new DateTime(1999, 12, 31));
                john.TimeTravel(new DateTime(1950, 12, 25));
            }
            catch (PersonException ex)
            {
                WriteLine(ex.Message);
            }



            // BOOK: page 218 Extending types when you cannot inherit (sealed)   ---------------------------------------------------------------------
            string email1 = "*****@*****.**";
            string email2 = "test&test.com";

            WriteLine("{0} is a valid email address: {1}",
                      arg0: email1,
                      arg1: StringExtensions.IsValidEmail(email1));

            WriteLine("{0} is a valid email address: {1}",
                      arg0: email2,
                      arg1: StringExtensions.IsValidEmail(email2));

            WriteLine("{0} is a valid email address: {1}",
                      arg0: email1,
                      arg1: email1.IsValidEmail());

            WriteLine("{0} is a valid email address: {1}",
                      arg0: email2,
                      arg1: email2.IsValidEmail());
        }