## Saturday, June 24, 2006

### Variance in C# Generics to Follow Scala

This paper by Burak Emir, Andrew J. Kennedy, Claudio Russo, Dachuan Yu, slated for ECOOP 2006, has proposed modeling variance in C# generics in line very much similar to what Scala does. The proposed notation is based on definition-site declarations (as in Scala) and uses +/- to model covariance / contravariance, as also in Scala.

This proposed extension will make the following declarations possible:

// Covariant parameters used as result typesinterface IEnumerator<+T> { T Current { get; } }// Covariant parameters used in covariant result typesinterface IEnumerable<+T> { IEnumerator<T> GetEnumerator(); }// Contravariant parameters used as argument typesinterface IComparer<-T> { int Compare(T x, T y); }

Here is the corresponding syntax in Scala using a covariant type parameter:

class Array[+a] {  def apply(index: int): a  ...}

In order to ensure type-safety through static type checking, the new extension to variance annotations in C# allows covariant parameters only in producer positions in signatures and contravariant paramaters only in consumer positions. These restrictions are, however, overcome through the use of type constraints:

class List<+T> {   ...  List<U> Append<U>(U other) where T : U { ... }  List<U> Append<U>(List<U> other) where T : U { ... }  ...}

Quite similarly we have the same solution in Scala by using a polymorphic method with a lower type parameter bound:

class Stack[+a] {  def push[b >: a](x: b): Stack[b]     = new NonEmptyStack(x, this)  ...}

As a sidenote, it may be mentioned that Java Generics addresses the variance problem by employing wildcards and using use-site declarations (as opposed to defintion-site in C# and Scala).