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.
How is out keyword associated to type co-variance?
-
30-06-2022 - |
Frage
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.
Lösung 2
Andere Tipps
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
- To create new instance of a class.
object obj = new object();
- To explicitly shadow base class method or property.
protected new void BaseMethod(){}
- 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.