static void CovarianceDemo1()
        {
            var ls = new List <Sub>();
            var lb = new List <Base>();


            var b = new Base();
            var s = new Sub();

            ls.Add(s);
            lb.Add(b);

            // ls.Add(b); error
            lb.Add(s);

            DoSomething(ls);
            // DoSomething2(ls); error

            var fooin  = new FooIn <Sub>();
            var fooout = new FooOut <Sub>();

            IFooIn <Sub> returnValueIn = GetFooIn();

            //IFooOut<Sub> returnValueOut = GetFooOut();

            // GetFooIn(fooin); illeagal due to covariance rules
            GetFooOut(fooout); // legal due to covariance rules
        }
        static void CovarianceDemo2()
        {
            // In-variant
            //IFoo<Base> ifbase = new Foo<Sub>();
            //IFoo<Sub> ifsub = new Foo<Base>();

            // Co-variance
            IFooOut <Base> ifbase = new FooOut <Sub>();
            //IFooOut<Sub> ifsub = new FooOut<Base>();

            // Contra-variance
            //IFooIn<Base> infbase = new FooIn<Sub>();
            IFooIn <Sub> infsub = new FooIn <Base>();

            IEnumerable <int> listInt = new List <int> {
                1, 2, 3
            };
            IEnumerable <object> someObjects = (IEnumerable <object>)listInt;

            Func <Base, Sub> func   = n => new Sub();
            Action <int>     action = n => Console.WriteLine(n);

            GetFunc(func);
        }