Question

I was reading the Covariance and Contravariance in C#.

According to my understanding,

If we have a class Animal and a derived class Cat then,

Covariance feature makes the compiler accepts passing a Cat type object to Animal type object and Contravariant is vice-versa.

Everything is ok till I read this line.

"To annotate type-covariance you use out parameter and for contravariant you use in parameter"

According to me, a parameter decorated with out keyword => the value must be assigned to that particular parameter in a function.

I have difficulties to associate the out keyword to covariance and in keyword to contravariant.

How are these two related ? Any super simple examples for both?

Thanks in advance.

Was it helpful?

Solution 2

out is a contextual keyword, i.e. depending on its placement, it means different things.
You are talking about the parameter modifier. But that's not what it is with regards to Co- and Contravariance. When the keyword is used in a generic interface definition, it is the generic modifier, which is something else completely.

OTHER TIPS

Both covariance and contravariance in C# 4.0 refer to the ability of using a derived class instead of base class. The in/out keywords are compiler hints to indicate whether or not the type parameters will be used for input and output. Covariance

Covariance in C# 4.0 is aided by out keyword and it means that a generic type using a derived class of the out type parameter is OK. Hence

IEnumerable<Fruit> fruit = new List<Apple>();

Since Apple is a Fruit, List can be safely used as IEnumerable Contravariance

Contravariance is the in keyword and it denotes input types, usually in delegates. The principle is the same, it means that the delegate can accept more derived class.

public delegate void Func<in T>(T param);

This means that if we have a Func, it can be converted to Func.

Func<Fruit> fruitFunc = (fruit)=>{};
Func<Apple> appleFunc = fruitFunc;

Why are they called co/contravariance if they are basically the same thing?

Because even though the principle is the same, safe casting from derived to base, when used on the input types, we can safely cast a less derived type (Func) to a more derived type (Func), which makes sense, since any function that takes Fruit, can also take Apple.

out keyword serves different purposes. As you noted in the context of "generic type parameters" it acts as a keyword to make "covariance" work, another use is similar to ref keyword which we use to get multiple return values from a Method.

If you look at the documentation for out-keyword in MSDN two purposes of out keyword will be listed. Not to be confused it acts different based on the context.

You can find similarities with new keyoword also, it also serves different purposes. AFAIK they are

  1. To create new instance of a class. object obj = new object();
  2. To explicitly shadow base class method or property. protected new void BaseMethod(){}
  3. Generic parameter constraint. private void MyGenericMethod<T>(T t) where T:new()

I think Microsoft guys make this feature very complexe by using not clear names for the feature name and not good keywords for the feature parameters.

I know this name from Covariance and contravariance of vectors (Mathe) and when I hear about it first time in C# I got a shock!

@JoesphAlbahari in his book C# 4 In a Nutshell have explained this topic very well page 109-112. I recommend you really to read it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top