Tutorial by Examples: covariance



string[] strings = new[] {"foo", "bar"}; 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[] {"Foo"}; object[] objects = strings;...
The + symbol marks a type parameter as covariant - here we say that "Producer is covariant on A": trait Producer[+A] { def produce: A } A covariant type parameter can be thought of as an "output" type. Marking A as covariant asserts that Producer[X] <: Producer[Y] prov...
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...
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...
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...
When is an IEnumerable<T> a subtype of a different IEnumerable<T1>? 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