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.
1905 questions
11
votes
3 answers

Why are C# arrays covariant and what benefits does it bring?

I'm having trouble understanding why arrays in C# are covariant and what benefits this covariance can bring. Consider the following trivial code example: object[] myArray = new string[1]; myArray[0] = 1; This code will compile okay, but will…
Matt B
  • 8,315
  • 2
  • 44
  • 65
11
votes
3 answers

Why does the following example using covariance in delegates not compile?

I have defined the following delegate types. One returns a string, and one an object: delegate object delobject(); delegate string delstring(); Now consider the following code: delstring a = () => "foo"; delobject b = a; //Does not compile! Why is…
tigrou
  • 4,236
  • 5
  • 33
  • 59
11
votes
3 answers

What are the kinds of covariance in C#? (Or, covariance: by example)

Covariance is (roughly) the ability to mirror inheritance of "simple" types in complex types that use them. E.g. We can always treat an instance of Cat as an instance of Animal. A ComplexType may be treated as a ComplexType, if…
Cristian Diaconescu
  • 34,633
  • 32
  • 143
  • 233
11
votes
2 answers

Python package that supports weighted covariance computation

Is there a python statistical package that supports the computation of weighted covariance (i.e., each observation has a weight) ? Unfortuantely numpy.cov does not support weights. Preferably working under numpy/scipy framework (i.e., able to use…
CuriousMind
  • 15,168
  • 20
  • 82
  • 120
10
votes
3 answers

.NET 4.0 Covariance

In response to another question I have tried to do the following. I don't think I interpreted that question correctly, but I do wonder if the below is possible somehow (my attempts have failed) and if not why not: public class MyBaseClass { } …
Myles McDonnell
  • 12,943
  • 17
  • 66
  • 116
10
votes
2 answers

About Generics and Inheritance (forgive my bad title)

As I don't know how my problem is called, I cannot guarantee, that nobody has asked the same question recently or at all. I did notice, however that there are quite a few threads with a similar title, but they don't seem to be relevant to my…
Nolonar
  • 5,962
  • 3
  • 36
  • 55
10
votes
3 answers

How to initialize covariant variable?

class C [+T] { var v : T = _ } compiler error: covariant type T occurs in contravariant position in type T of value value_= why? how can I fix it?
rastafarra
  • 131
  • 4
10
votes
3 answers

Wildcards in C# generic constraints

I'm aware that C# doesn't have generic wildcards, and that a similar effect can be achieved by generic methods, but I need to use a wildcard in a field and can't work out if there is any way to encode it. List> list; void…
zmthy
  • 568
  • 3
  • 13
10
votes
1 answer

C++, ambiguous inheritance error in vs 2010

I have some troubles with the application of polymorphism in this example. This question is similar to my last question C++, virtual inheritance, strange abstract class + clone problem There are 3 abstract classes: class A { public: virtual A *…
Johnas
  • 1,263
  • 3
  • 12
  • 23
10
votes
5 answers

covariant return types with multiple inheritance. how does this code work?

Can anyone tell me how does return type covariance work in the following code? class X { public: int x; }; class Y: public OtherClass, public X { }; static Y inst; class A { public: virtual X* out() = 0; }; class B : public A { …
Leo
  • 309
  • 3
  • 8
10
votes
2 answers

Contravariance invalid when using interface's delegate as a parameter type

Consider the contravariant interface definition with a delegate: public interface IInterface { delegate int Foo(int x); void Bar(TInput input); void Baz(TInput input, Foo foo); } The definition of Baz fails with an…
V0ldek
  • 9,623
  • 1
  • 26
  • 57
10
votes
3 answers

Why is List not valid on an covariant interface MyInterface

Follow up question to a previous question, this has been identified as a co-variance issue. Taking this one step further, if I modify IFactory as follows: class Program { static void Main(string[] args) { IFactory factory =…
Firoso
  • 6,647
  • 10
  • 45
  • 91
10
votes
3 answers

Question about generics in C# comparing to Java

In Java I can specify generic with wildcard "?". It is possible to create a map like this one: Map. I'm working with C# and I need a Dictionary> (where ? can be int, double, any type). Is this possible in…
aumanets
  • 3,703
  • 8
  • 39
  • 59
10
votes
2 answers

What does it mean that Box is covariant if Box is not a subtype of Box where B: A?

After I read the subtyping chapter of the Nomicon, I couldn't wrap my head around covariance of a type parameter. Especially for the Box type, which is described as: T is covariant. However, if I write this code: trait A {} trait B: A {} struct…
LVB
  • 382
  • 4
  • 18
10
votes
1 answer

Vectorizing NumPy covariance for 3D array

I have a 3D numpy array of shape (t, n1, n2): x = np.random.rand(10, 2, 4) I need to calculate another 3D array y which is of shape (t, n1, n1) such that: y[0] = np.cov(x[0,:,:]) ...and so on for all slices along the first axis. So, a loopy…
dayum
  • 1,073
  • 15
  • 31