# Tutorial by Examples: covariance

## Array covariance

string[] strings = new[] {&quot;foo&quot;, &quot;bar&quot;}; object[] objects = strings; // implicit conversion from string[] to object[] This conversion is not type-safe. The following code will raise a runtime exception: string[] strings = new[] {&quot;Foo&quot;}; object[] objects = strings;...

## Covariance

The + symbol marks a type parameter as covariant - here we say that &quot;Producer is covariant on A&quot;: trait Producer[+A] { def produce: A } A covariant type parameter can be thought of as an &quot;output&quot; type. Marking A as covariant asserts that Producer[X] &lt;: Producer[Y] prov...

## Covariance of a collection

Because collections are typically covariant in their element type*, a collection of a subtype may be passed where a super type is expected: trait Animal { def name: String } case class Dog(name: String) extends Animal object Animal { def printAnimalNames(animals: Seq[Animal]) = { anima...

## Array Covariance

Object arrays are covariant, which means that just as Integer is a subclass of Number, Integer[] is a subclass of Number[]. This may seem intuitive, but can result in surprising behavior: Integer[] integerArray = {1, 2, 3}; Number[] numberArray = integerArray; // valid Number firstElement = numb...

## Covariance on an invariant trait

There is also a way to have a single method accept a covariant argument, instead of having the whole trait covariant. This may be necessary because you would like to use T in a contravariant position, but still have it covariant. trait LocalVariance[T]{ /// ??? throws a NotImplementedError de...

## Covariance

When is an IEnumerable&lt;T&gt; a subtype of a different IEnumerable&lt;T1&gt;? When T is a subtype of T1. IEnumerable is covariant in its T parameter, which means that IEnumerable's subtype relationship goes in the same direction as T's. class Animal { /* ... */ } class Dog : Animal { /* ... */ }...

Page 1 of 1