From Wikipedia:
covariant: converting from wider (double) to narrower (float).
contravariant: converting from narrower (float) to wider (double).
In .NET, a delegate has covariance because it allows for derived types of the delegate’s specified return type to be the return type of a method that it holds a reference to.
As well a delegate has contravariance because it allows for derived types of the delegate’s specified arguments (parameters) to be the argument type passed into the method that it holds a reference to.
With these two definitions as they pertain to delegates, shouldn’t they both be covariance? In both cases, the delegate expects a “wider” type, but is given a “narrower type”.
See here for an example of both from MSDN.
So how does the word contravariance make sense, linguistically, when pertaining to delegates?
I now disagree with the answer from SeanVDH. He says “Linguistically, this seems to be logical in the sense of parameters versus return- so the direction forward or backward is with regards to going in or coming out of the function”.
Instead I think this is the answer which comes from here:
Covariance preserves assignment compatibility and contravariance reverses it. Covariance is a widening conversion, and contravariance is a narrowing conversion.
Example:
This realization was the result of reading Eric Lippert’s article, the Covariance and contravariance section of the Fast-tracked delegates chapter in Jon Skeet’s book C# In Depth, as well as the link above where the quote was drawn from.