public static void ShowSomeDogInformation(Dog dog)
 {
     Console.WriteLine("Name:" + dog.Name + " Age: " + dog.Age);
 }
 private static string GenericTester(Func <object, object> p, Dog mammal)
 {
     return(mammal.GetDetails());
 }
        static void Main(string[] args)
        {
            #region Assessment A

            // the below class declarations looks like a 1st year student developed it
            // NOTE: this includes the class declarations as well
            // IMPROVE THE ARCHITECTURE

            // instantiated the class by using an object initializer
            Human human = new Human
            {
                Name   = "John",
                Age    = 35,
                Gender = "M"
            };
            Console.WriteLine(human.GetDetails());

            // instantiated the class by using an object initializer
            Dog dog = new Dog
            {
                Name = "Walter",
                Age  = 7,
                Food = "Epol"
            };
            Console.WriteLine(dog.GetDetails());

            // instantiated the class by using an object initializer
            Cat cat = new Cat
            {
                Name = "Snowball",
                Age  = 35,
                Food = "Whiskers"
            };
            Console.WriteLine(cat.GetDetails());

            #endregion

            #region Assessment B

            // you'll notice the following piece of code takes an
            // age to execute - CORRECT THIS
            // IT MUST EXECUTE IN UNDER A SECOND
            PerformanceTest();

            #endregion

            #region Assessment C

            // correct the following LINQ statement found in their respective methods
            var numbers = new List <int>()
            {
                1, 4, 5, 9, 11, 15, 20, 27, 34, 55 // you may not change the numbers
            };
            // the following method must return the first event number - as suggested by it's name
            var firstValue = GetFirstEvenValue(numbers);
            Console.WriteLine("First Number: " + firstValue);

            var strings = new List <string>()
            {
                "John", "Jane", "Sarah", "Pete", "Anna"
            };
            // the following method must return the first name which contains an 'a'
            var strValue = GetSingleStringValue(strings);
            Console.WriteLine("Single String: " + strValue);

            #endregion

            #region Assessment D

            // there are multiple corrections required!!
            // correct the following statement(s)
            try
            {
                Dog bulldog = null;
                if (bulldog != null)//check if the object is null and dispose of it if it is
                {
                    var disposeDog = (IDisposable)bulldog;
                    disposeDog.Dispose();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            #endregion

            #region Assessment E

            DisposeSomeObject();

            #endregion

            #region Assessment F

            // # SECTION A #
            // by making use of generics improve the implementation of the following methods
            // output must still render as: Name: [name] Age: [age]
            // THE METHOD THAT YOU CREATE MUST BE STATIC AND DECLARED IN THE PROGRAM CLASS
            // NB!! PLEASE NAME THE METHOD: ShowSomeMammalInformation
            ShowSomeHumanInformation(human);
            ShowSomeDogInformation(dog);
            ShowSomeCatInformation(cat);

            //using the ShowMammalInformation Generic Method
            // I am using generic method
            ShowSomeMammalInformation(human.Name, human.Age);
            ShowSomeMammalInformation(dog.Name, dog.Age);
            ShowSomeMammalInformation(cat.Name, cat.Age);


            // # SECTION B #
            // BY MAKING USE OF REFLECTION (amongst other things):
            //      => create a method so that the below code snippet will work:
            //      => place a constraint on the new method, so that a new instance will be created when 'dog' is null
            //      => thus is dog = null, the method should create a new instance an not fail

            // UNCOMMENT THE FOLLOWING PIECE OF CODE - IT WILL CAUSE A COMPILER ERROR - BECAUSE YOU HAVE TO CREATE THE METHOD

            string a = Program.GenericTester(walter => walter.GetDetails(), dog);
            Console.WriteLine("Result A: {0}", a);
            int b = Program.GenericTester(snowball => snowball.Age, cat);
            Console.WriteLine("Result B: {0}", b);

            #endregion

            #region Assessment G

            // in the following statement, everything works fine
            // but, it has a huge flaw!
            // correct the following piece of code
            try
            {
                CatchAndRethrowExplicitly();
            }
            catch (ArithmeticException e)
            {
                Console.WriteLine("Implicitly specified:{0}{1}", Environment.NewLine, e.StackTrace);
            }

            #endregion

            #region Assessment H

            try
            {
                // REFLECTION TEST .... NAVIGATE TO THE BELOW METHOD TO GET ALL THE INSTRUCTIONS
                CallMethodWithReflection();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            #endregion

            #region IoC / DI

            // everything can be viewed in this method....
            PerformIoCActions();

            #endregion

            #region Bonus XP - Dungeon

            // > UNCOMMENT THE CODE BELOW AND CREATE A METHOD SO THAT THE FOLLOWING CODE WILL WORK
            // > DECLARE ALL THE METHODS WITHIN THE PROGRAM CLASS !!
            // > DO NOT ALTER THE EXISTING CODE


            const string abc = "asduqwezxc";


            foreach (var vowel in SelectOnlyVowels(abc))
            {
                Console.WriteLine("{0}", vowel);
            }

            // < REQUIRED OUTPUT => a u e

            // > UNCOMMENT THE CODE BELOW AND CREATE A METHOD SO THAT THE FOLLOWING CODE WILL WORK
            // > DECLARE ALL THE METHODS WITHIN THE PROGRAM CLASS !!
            // > DO NOT ALTER THE EXISTING CODE

            // methods created in the assessment method region.
            //created methods are the "customWhere" and SelectOnlyVowels
            List <Dog> dogs = new List <Dog>
            {
                new Dog {
                    Age = 8, Name = "Max"
                },
                new Dog {
                    Age = 3, Name = "Rocky"
                },
                new Dog {
                    Age = 9, Name = "XML"
                }
            };

            var foo = dogs.CustomWhere(x => x.Age > 6 && x.Name.SelectOnlyVowels().Any());

            // < DOGS REQUIRED OUTPUT =>
            //      Name: Max Age: 8

            List <Cat> cats = new List <Cat>
            {
                new Cat {
                    Age = 1, Name = "Capri"
                },
                new Cat {
                    Age = 8, Name = "Cara"
                },
                new Cat {
                    Age = 3, Name = "Captain Hooks"
                }
            };

            var bar = cats.CustomWhere(x => x.Age <= 4);

            // < CATS REQUIRED OUTPUT =>
            //      Name: Capri Age: 1
            //      Name: Captain Hooks Age: 3

            #endregion

            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }