C# (also suitable for Java) contravariance and covariance in simple words
Ever wondered what covariance and contravariance are? Confused with msdn explanation and want to hear something easy to catch? This article is for you.
There are TWO explanations for you. The first one is more technical, and the second one if you did not understand the first explanation.
Technical and more complex explanation
Covariance and contravariance in C# refer to how data types can be converted, especially in the context of generics and delegates. In simple terms, these concepts help you to achieve more flexibility and type safety when working with related types (inheritance or interfaces). Let’s break it down:
- Covariance: Covariance allows you to use a more derived type (a subclass) in place of a less derived type (a superclass). In other words, you can use a derived class where the base class is expected. In C#, this is supported for matching method signatures with delegate types and for generic type arguments.
For example, consider you have a class hierarchy with a base class Animal
and a derived class Mammal
. If you have a method that returns an IEnumerable<Animal>
, you can use covariance to treat it as IEnumerable<Mammal>
if the method actually returns an enumerable of mammals.
- Contravariance: Contravariance allows you to use a less derived type (a superclass) in place of a more derived type (a subclass). In other words, you can use a base class where a derived class is expected. In C#, contravariance is supported for matching method signatures with delegate types and for generic type arguments.
For example, consider the same class hierarchy mentioned above with the base class Animal
and derived class Mammal
. If you have a method that takes an Action<Mammal>
delegate, you can use contravariance to pass an Action<Animal>
delegate instead
Time for the easy explanation!
Alright, let’s use a real-world analogy to explain covariance and contravariance without any programming jargon.
Imagine you have a group of animals, where some animals are mammals (like dogs and cats), and some are not mammals (like birds and fish).
Now, let’s say you have a box of animals and a box of mammals. The box of animals can contain any animal, while the box of mammals can only contain mammals.
- Covariance: Think of covariance as a rule that says, “If you need a box of animals, you can also use a box of mammals.” This is because all mammals are animals, so a box of mammals still meets the requirement of a box of animals.
- Contravariance: Contravariance is a rule that says, “If you need a box of mammals, you can also use a box of animals.” However, this rule only works if you make sure that the animals you put in the box are actually mammals. This allows for greater flexibility, but you need to be careful not to put non-mammal animals in the box, as that would violate the rule.
In both cases, covariance and contravariance help you to use more specific or more general categories (like mammals and animals) interchangeably under certain conditions, providing flexibility in non-programming situations.