Covariance and Contravariance in C#3

Posted on Tue 04 April 2017 in blog

A short introduction to Covariance and Contravariance in C# 3 preparing you to an article about that in C# 4. So what is covariance? Covariance is basically using a method which returns something derived from the expected type. An exemple? It's safe to have a method returning a cat when you expect it to return an animal. In C sharp it's

public class Animal
{
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

// It's safe to say that something returns a Animal when in fact this thing returns a Cat
class Covariance
{
    void test()
    {
        Func a = Method; // OK
        Func b = delegate { return new Cat(); }; // OK
        Func c = () => new Cat(); // OK
    }

    Cat Method()
    {
        return new Cat();
    }
}

So Funcs a, b, and c are returning animals which in fact are cats, which is true. And, what is contravariance? Contravariance is basically using a method which takes something which is a parent of the expected type. An exemple? It's safe to give a method an animal when it expects to receive a cat.

// It's safe to say that something can take a Cat if in fact this thing can take any Animal
class Contravariance
{
    static void test()
    {
        Action a = Method; // OK
        Action b = delegate(Animal value) { }; // ERROR
        // From C#3 Specification :
        // $7.14.1 Anonymous function signatures :
        // [...] contra-variance of anonymous function parameter types is not supported.
        Action d = (Animal value) => { }; // idem... anonymous... not supported.
    }

    public static void Method(Animal value)
    {
    }
}

So Action a take Cats, but in fact can take any Animals, so it's safe.