Questions tagged [covariance]

Covariance, contravariance and invariance describe how the existing type inheritance hierarchy changes when subjected to some transformation (such as usage within generics). If the transformation keeps the ordering of the original hierarchy, it is "covariant". If it reverses it, it is "contravariant". If it breaks it, it is "invariant".

About Type Ordering

Let's say that a class P (parent) is inherited by a class C (child).

We can denote this fact as: P > C.

Informally, P is "larger" than C since it "contains" all the possible instances of C, but can also contain some other instances that are not C. Child is always parent but not necessarily the other way around.

Variance in Generics

Let's say that there is a generic type G that has a single generic parameter T, denoted by: G{T}.

  • If G{P} > G{C}, then T is co-variant (it preserves the original inheritance ordering).
  • If G{P} < G{C}, then T is contra-variant (it reverses the original inheritance ordering).
  • If G{P} and G{C} are type-unrelated, then T is invariant (it "breaks" the inheritance).

So the variance is the property of transformation (in this case: generic parameter T of G), not the original type hierarchy (P and C).

C# Examples

The generic parameter T of IEnumerable<out T> is covariant (as denoted by "out" keyword), meaning you can "forget" that the collection contains Cs and just treat it as if it contains Ps. For example:

IEnumerable<C> ec = ...;
IEnumerable<P> ep = ec;

The generic parameter T of Action<in T> is contravariant (as denoted by "in" keyword), meaning that an action that accepts P can also accept C. For example:

Action<P> ap = ...;
Action<C> ac = ap;

The generic parameter T is contravariant and generic parameter TResult is covariant in Func<in T, out TResult>. Each generic parameter is considered a different "transformation" with its own variance. This lets you write a code like this:

Func<P, C> fpc = ...;
Func<C, P> fcp = fpc;

And finally, the generic parameter T of IList<T> is considered invariant, so IList<P> and IList<C> are considered unrelated types (there is no assignment compatibility in either direction).


Tag usage

  • Do not use for the measurement of the strength and direction of the linear relationship between two random variables (statistical context). Instead, use other related tags, for example, .
    Moreover, consider whether the question might be better suited to Cross Validated, the Stack Exchange site for statistics, machine learning and data analysis.
1751 questions
217
votes
5 answers

vs in Generics

What is the difference between and ? For example: public interface IExample { ... } vs. public interface IExample { ... }
Cole Johnson
  • 8,415
  • 15
  • 44
  • 66
204
votes
12 answers

Convert List to List

While we can inherit from base class/interface, why can't we declare a List<> using same class/interface? interface A { } class B : A { } class C : B { } class Test { static void Main(string[] args) { A a = new C(); // OK …
Asad
  • 19,788
  • 16
  • 65
  • 91
174
votes
9 answers

Why are arrays covariant but generics are invariant?

From Effective Java by Joshua Bloch, Arrays differ from generic type in two important ways. First arrays are covariant. Generics are invariant. Covariant simply means if X is subtype of Y then X[] will also be sub type of Y[]. Arrays are covariant…
eagertoLearn
  • 8,372
  • 22
  • 66
  • 108
172
votes
9 answers

Covariance and contravariance real world example

I'm having a little trouble understanding how I would use covariance and contravariance in the real world. So far, the only examples I've seen have been the same old array example. object[] objectArray = new string[] { "string 1", "string 2" }; It…
Razor
  • 16,811
  • 22
  • 87
  • 137
157
votes
5 answers

Difference between Covariance & Contra-variance

I am having trouble understanding the difference between covariance and contravariance.
jane doe
  • 1,613
  • 3
  • 11
  • 7
154
votes
4 answers

Why covariance and contravariance do not support value type

IEnumerable is co-variant but it does not support value type, just only reference type. The below simple code is compiled successfully: IEnumerable strList = new List(); IEnumerable objList = strList; But changing from…
cuongle
  • 69,359
  • 26
  • 132
  • 196
148
votes
7 answers

Co-variant array conversion from x to y may cause run-time exception

I have a private readonly list of LinkLabels (IList). I later add LinkLabels to this list and add those labels to a FlowLayoutPanel like follows: foreach(var s in strings) { _list.Add(new…
TheVillageIdiot
  • 38,082
  • 20
  • 126
  • 184
148
votes
4 answers

Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work?

Following on from this question, can someone explain the following in Scala: class Slot[+T] (var some: T) { // DOES NOT COMPILE // "COVARIANT parameter in CONTRAVARIANT position" } I understand the distinction between +T and T in the…
oxbow_lakes
  • 129,207
  • 53
  • 306
  • 443
127
votes
3 answers

Covariance, Invariance and Contravariance explained in plain English?

Today, I read some articles about Covariance, Contravariance (and Invariance) in Java. I read the English and German Wikipedia article, and some other blog posts and articles from IBM. But I'm still a little bit confused on what these exactly are…
anon
115
votes
2 answers

Problem understanding covariance contravariance with generics in C#

I can't understand why the following C# code doesn't compile. As you can see, I have a static generic method Something with an IEnumerable parameter (and T is constrained to be an IA interface), and this parameter can't be implicitly converted to…
BenLaz
  • 995
  • 1
  • 6
  • 8
110
votes
9 answers

What is a covariant return type?

What is a covariant return type in Java? In object-oriented programming in general?
Pops
  • 28,257
  • 34
  • 127
  • 149
106
votes
3 answers

Give examples of functions which demonstrate covariance and contravariance in the cases of both overloading and overriding in Java?

Please show a good example for covariance and contravariance in Java.
JavaUser
  • 22,494
  • 44
  • 98
  • 127
106
votes
2 answers

How is Generic Covariance & Contra-variance Implemented in C# 4.0?

I didn't attend PDC 2008, but I heard some news that C# 4.0 is announced to support Generic covariance and contra-variance. That is, List can be assigned to List. How could that be? In Jon Skeet's book C# in Depth, it is explained…
Morgan Cheng
  • 66,562
  • 63
  • 166
  • 223
98
votes
3 answers

Why is Scala's immutable Set not covariant in its type?

EDIT: Re-written this question based on original answer The scala.collection.immutable.Set class is not covariant in its type parameter. Why is this? import scala.collection.immutable._ def foo(s: Set[CharSequence]): Unit = { println(s) } def…
oxbow_lakes
  • 129,207
  • 53
  • 306
  • 443
88
votes
9 answers

Does C# support return type covariance?

I'm working with the .NET framework and I really want to be able to make a custom type of page that all of my website uses. The problem comes when I am trying to access the page from a control. I want to be able to return my specific type of page…
Kyle Sletten
  • 5,137
  • 2
  • 25
  • 38
1
2 3
99 100