Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between covariance and upcasting

What is the difference between covariance and upcasting, or, more specifically, why are they given different names?

I've seen the following example referred to as 'upcasting':

string s = "hello"; object o = s;  //upcast to 'string' to 'object' 

Whereas, the following I have seen called 'covariance':

string[] s = new string[100]; object[] o = s;  IEnumerable<string> ies = new List<string>(); IEnumerable<object> ieo = ies; 

Now, to my untrained eye, covariance seems to be the same as upcasting, except that it refers the casting of collections. (And of a similar statement can be made regarding contravariance and downcasting).

Is it really that simple?

like image 645
James Wiseman Avatar asked Jul 15 '11 13:07

James Wiseman


People also ask

What is meant by covariance and Contravariance?

Covariance and contravariance are terms that refer to the ability to use a more derived type (more specific) or a less derived type (less specific) than originally specified. Generic type parameters support covariance and contravariance to provide greater flexibility in assigning and using generic types.

What is the difference between covariance and Contravariance in C #?

In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.

Is Upcasting automatic?

This is called upcasting. Upcasting is done automatically, while downcasting must be manually done by the programmer, and i'm going to give my best to explain why is that so.

What is covariant in C#?

Covariance in C# Covariance enables you to pass a derived type where a base type is expected. Co-variance is like variance of the same kind. The base class and other derived classes are considered to be the same kind of class that adds extra functionalities to the base type.


1 Answers

Now, to my untrained eye, covariance seems to be the same as upcasting, except that it refers the casting of collections. (And of a similar statement can be made regarding contravariance and downcasting).

Is it really that simple?

Covariance isn't about upcasting, although I can see why you think it's related.

Covariance is about the following very simple idea. Let's say you have a variable derivedSequence of type IEnumerable<Derived>. Let's say you have a variable baseSequence of type IEnumerable<Base>. Here, Derived derives from Base. Then, with covariance, the following is a legal assignment, and an implicit reference conversion occurs:

baseSequence = derivedSequence; 

Note that this is not upcasting. It is not the case that IEnumerable<Derived> derives from IEnumerable<Base>. Rather, it is covariance that allows you to assign the value of the variable derivedSequence to the variable baseSequence. The idea is that variables of type Base can be assigned from objects of type Derived, and since IEnumerable<T> is covariant in its parameter, objects of type IEnumerable<Derived> can be assigned to variables of type IEnumerable<Base>.

Of course, I haven't yet really explained what covariance is. In general, covariance is about the following simple idea. Let's say you have a mapping F from types to types (I'll denote this mapping by F<T>; given a type T its image under the mapping F is F<T>.) Let's say that this mapping has the following very special property:

if X is assignment compatible with Y, then F<X> is assignment compatible with F<Y> as well.

In this case, we say that F is covariant in its parameter T. (Here, to say that "A is assignment compatible with B" where A and B are reference types means that instances of B can be stored in variables of type A.)

In our case, IEnumerable<T> in C# 4.0, an implicit reference conversion from instances of IEnumerable<Derived> to IEnumerable<Base> if Derived is derived from Base. The direction of assignment compatibility is preserved, and this is why we say that IEnumerable<T> is covariant in its type parameter.

like image 128
jason Avatar answered Oct 07 '22 06:10

jason