Search code examples
c#delegatescovariancecontravariance

Covariance and Contravariance of Delegates


There is something I am not understanding about covariance and contravariance of delegates. What's the rationale behind flexibility to downcast parameters and to upcast return types

As an example, say we have

  1. Person as a Superclass and Teacher as a Subclass of Person
  2. ReturnPersonDelagate that represents a method that returns a person
  3. TeacherParameterDelegate that represents method that take an employee object as a parameter

You can

  1. assign a method that return a Teacher to ReturnPersonDelagate (upcasting)
  2. assign a method that takes Person as a parameter TeacherParameterDelegate (downcasting)

I am a bit confused. What's the rationale behind this concept and why is downcasting supported implicitly?


Solution

  • It makes perfect sense. Take a look:

    public class Program
    {
        public static void Main()
        {
            Del d = Method;
            var p = d(new Teacher());
        }
    
        public delegate Person Del(Teacher t);
    
        public static Teacher Method(Person p)
        {
            return new Teacher();
        }
    }
    
    public class Person {}
    public class Teacher : Person {}
    

    Method returns a Teacher object which is always of type Person but imagine you swap the types and make the Del return a more specific type and Method to return a more general type. The code would not work and would not make sense at all. But in this case, it does as you always get a correct type that can be converted implicitly to the return type of the Del. Also, the type of the parameter of the Del type is more specific than the one Method accepts as it also makes sense. If you would swap them for example you could invoke the Method with the incorrect type but in this case, it is fine as the Teacher object will always be of type Person.