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
13
votes
2 answers

Numpy Cholesky decomposition LinAlgError

In my attempt to perform cholesky decomposition on a variance-covariance matrix for a 2D array of periodic boundary condition, under certain parameter combinations, I always get LinAlgError: Matrix is not positive definite - Cholesky decomposition…
neither-nor
  • 1,245
  • 2
  • 17
  • 30
13
votes
2 answers

KeyValuePair Covariance

Is there a better way to mimic Covariance in this example? Ideally I'd like to do: private IDictionary> foos; public IEnumerable> Foos { get { return foos; …
Ben Foster
  • 34,340
  • 40
  • 176
  • 285
13
votes
7 answers

How can i cast into a ObservableCollection
How can i cast from ObservableCollection into ObservableCollection this doesnt work for me (ObservableCollection)myTabItemObservableCollection
Mario Binder
  • 1,604
  • 4
  • 16
  • 24
12
votes
1 answer

Build in function for computing covariance

Is there a way in python to obtain the covariance matrix given the mean and sample data points Example: mean = [3 3.6] data = [[1 2] [2 3] [3 3] [4 5] [5 5]] I know how to calculate the same by substituting these…
Jannat Arora
  • 2,759
  • 8
  • 44
  • 70
12
votes
2 answers

How to check covariant and contravariant position of an element in the function?

This is a code snippet from one of the articles that I read regarding contravariance and covariance in scala. However, I fail to understand the error message thrown by the scala compiler "error: covariant type A occurs in contravariant position in…
Chaitanya
  • 3,590
  • 14
  • 33
12
votes
7 answers

Covariance and Contravariance on the same type argument

The C# spec states that an argument type cannot be both covariant and contravariant at the same time. This is apparent when creating a covariant or contravariant interface you decorate your type parameters with "out" or "in" respectively. There is…
William Edmondson
  • 3,619
  • 3
  • 32
  • 41
12
votes
2 answers

Is C# 4.0 Tuple covariant

(I would check this out for myself, but I don't have VS2010 (yet)) Say I have 2 base interfaces: IBaseModelInterface IBaseViewInterface And 2 interfaces realizing those: ISubModelInterface : IBaseModelInterface ISubViewInterface :…
RichK
  • 11,318
  • 6
  • 35
  • 49
12
votes
2 answers

Covariance and Contravariance with C# Arrays

While reading a section of an article about covariance and contravariance at Wikipedia, I ran into the following, bolded sentence: First consider the array type constructor: from the type Animal we can make the type Animal[] ("array of animals").…
wjmolina
  • 2,625
  • 2
  • 26
  • 35
12
votes
2 answers

Can/should Task be wrapped in a C# 5.0 awaitable which is covariant in TResult?

I'm really enjoying working with C# 5.0 asynchronous programming. However, there are a few places where updating old code to be consistent with the TAP model is causing problems for me. Here's one of them - I'm not sure exactly why Task is…
lightw8
  • 3,262
  • 2
  • 25
  • 35
11
votes
1 answer

OCaml, meaning of `!+` in `type `!+'a t`

I'm currently learning about OCaml, and especially functors. I looked at map.mli from the standard library, and around line 70, there is : type key (** The type of the map keys. *) type !+'a t (** The type of maps from type [key] to type ['a].…
Felix Bertoni
  • 400
  • 2
  • 10
11
votes
1 answer

Type Members and Covariance

I guess, "type variance annotations" (+ and -) cannot be applied to "type members". In order to explain it to myself I considered the following example abstract class Box {type T; val element: T} Now if I want to create class StringBox I have to…
Michael
  • 10,185
  • 12
  • 59
  • 110
11
votes
1 answer

How to determine type parameter's variance?

Inspired by Real-world examples of co- and contravariance in Scala I thought a better question would be: When designing a library, are there a specific set of questions you should ask yourself when determining whether a type parameter should be…
Bradford
  • 4,143
  • 2
  • 34
  • 44
11
votes
2 answers

Can I implement an interface that contains a property that is of child type to what is required by the interface?

I am receiving the following error: ClassName.PropertyName cannot implement IClassType.PropertyName because it does not have the matching return type of IBasePropertyType Now, for the code: public class ClassName : IClassType { public…
Mark Avenius
  • 13,679
  • 6
  • 42
  • 50
11
votes
4 answers

How to compute rolling covariance more efficiently

I am trying to compute a rolling covariance between a set of data (each column of my x variable) and one other (y variable) in R. I thought I could use one of the apply functions, but can not find how to roll two set of inputs at the same time. Here…
Djiggy
  • 235
  • 2
  • 13
11
votes
5 answers

Any sensible solution to the lack of array/slice covariance in Go?

The problem I've just faced is what to do in the following case: func printItems(header string, items []interface{}, fmtString string) { // ... } func main() { var iarr = []int{1, 2, 3} var farr = []float{1.0, 2.0, 3.0} printItems("Integer…
PGene
  • 442
  • 4
  • 9