Covariance and Contravariance with delegates using C#

Most of us have heard of Covariance and Contravariance. Let me review their definition once more. Covariance is assigning an object of a more derived type to an object of a less derived type and Contravariance is the opposite of it .An object instantiated with a less derived type argument is assigned to an object instantiated with a more derived type argument. Assignment compatibility is reversed in this case.


Today I will explain Covariance and Contravariance in the context of delegates. They provide flexibility when assigning methods to delegate variables. They basically provide the freedom to treat the return type and parameters of a delegate polymorphically.

Covariance lets a method return a value from a subclass of the result expected by a delegate. For example, assume the Student class is derived from the Person class and the ReturnPersonPerformanceDelegate type represents methods that return a Person object. Then you could set a _delReturnPersonPerformance variable equal to a method that returns a Student because Student is a subclass of Person. This makes sense because the method should return a Person and a Student is a kind of Person.


Contravariance lets a method take parameters from a superclass of the type expected by a delegate. For example, assume the PersonParameterPerformanceDelegate type represents methods that take a Teacher object as a parameter. Then you could set a delReturnPersonPerformancevariable equal to a method that takes a Person as a parameter because Person is a superclass of Teacher. When you invoke the delegate variables method, you will pass it a Teacher (because the delegate requires that the method take an Employee parameter) and a Teacher is a kind of Person, so the method can handle it.

To summarize, covariance helps preserve assignment compatibility whereas contravariance reverses it.