namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter12.Listing12_44
{
    class Fruit { }

    class Apple : Fruit { }

    class Orange : Fruit { }


    interface ICompareThings<in T>
    {
        bool FirstIsBetter(T t1, T t2);
    }

    class Program
    {

        class FruitComparer : ICompareThings<Fruit>
        {
            // ...
            #region Wygenerowana namiastka interfejsu
            public bool FirstIsBetter(Fruit t1, Fruit t2)
            {
                throw new System.NotImplementedException();
            }
            #endregion Wygenerowana namiastka interfejsu
        }
        static void Main()
        {
            // Dozwolone w wersji C# 4.0
            ICompareThings<Fruit> fc = new FruitComparer();

            Apple apple1 = new Apple();

            Apple apple2 = new Apple();
            Orange orange = new Orange();

            // Obiekt typu FruitComparer może porównywać jabłka (Apple) z pomarańczami (Orange),
            bool b1 = fc.FirstIsBetter(apple1, orange);
            // a także jabłka z jabłkami.
            bool b2 = fc.FirstIsBetter(apple1, apple2);
            // Jest to dozwolone, ponieważ używany interfejs umożliwia kontrawariancję.
            ICompareThings<Apple> ac = fc;
            // W rzeczywistości obiekt jest typu FruitComparer, dlatego
            // też może porównywać dwa jabłka.
            bool b3 = ac.FirstIsBetter(apple1, apple2);
        }
    }
}