Contravariance in c#

Related to covariance is contravariance. Contravariance is the opposite to covariance, and allows you to
use a more general class when a specific class should be used. Contravariance uses the In modifier to
specify the parameter can only occur in the input position. You can add the In modifier to your own
interfaces and delegates, and it has been added to the following generic interfaces and delegates:
·         Comparer<in T>
·         EqualityComparer <in T>
·         Func<in T,.., out R>
·         Action<in T,..>
·         Predicate<in T>
·         Comparison<in T>
·         EventHandler<in T>
Example of Contravariance

Let’s say we want to create a common class that will sort animals by weight. It would be great if we could
use this same class to weigh anything that had a base class of Animal, but as you can guess the code we
will write won’t work in VS2008.

We will add Weight and Name properties to the Animal class so we can easily identify individual Animal
instances.

1. Create the Animal class so it now looks like:

public class Animal   
{       
        public int Weight { get; set; }
        public string Name { get; set; }
        public Animal()
        { }
        public Animal(string InputName, int InputWeight)
        {
            Name = InputName;
            Weight = InputWeight;
        }
    }

2. Now create the Elephant class to the following:

public class Elephant : Animal
    {
        public Elephant(string InputName, int InputWeight)
            : base(InputName, InputWeight)
        {
        }
    }
3. To weigh all our animals, we will create a new class called WeightComparer that will implement
the IComparer interface; implementing the IComparer interface will then enable us to

public class WeightComparer : IComparer<Animal>
    {
        public int Compare(Animal x, Animal y)
        {
            if (x.Weight > y.Weight) return 1;
            if (x.Weight == y.Weight) return 0;
            return -1;
        }
    }

Call this from Main

        static void Main(string[] args)
        {
            WeightComparer objAnimalComparer = new WeightComparer();
            List<Animal> Animals = new List<Animal>();
            Animals.Add(new Animal("elephant", 500));
            Animals.Add(new Animal("tiger", 100));
            Animals.Add(new Animal("rat", 5));
            //Works
            Animals.Sort(objAnimalComparer);
            List<Elephant> Elephants = new List<Elephant>();
            Elephants.Add(new Elephant("Nellie", 100));
            Elephants.Add(new Elephant("Dumbo", 200));
            Elephants.Add(new Elephant("Baba", 50));
            //Doesn't work prior to .net 4
            Elephants.Sort(objAnimalComparer);
            Elephants.ForEach(e => Console.WriteLine(e.Name + " " + e.Weight.ToString()));
             Console.Read();
        }

No comments:

Post a Comment