I'm new to c# but relatively experienced with scala, I'm trying to make a mimic of scala's list class (which is extended by Cons and the static class Nil). I was hoping to get the type behaviour it had as well, since .NET has supported covariance/contravariance since 4.0. Allow me to show what I mean:
Scala REPL:
class A
class B extends A
class C extends A
val x = new B() :: new B()
//this is type List[B]
val y = new C() :: new C()
//this is type List[C]
val z = new C() :: x
//This uses contravariance to figure out and infer that this is type List[A]!!!
In C# this will throw a compiler error because C and B are not the same type with ImmutableList.
There don't seem to be examples online and I'm still quite the novice with C# so I thought it would be wise to ask if C# could do this in any way before attempting blindingly (I am still trying but I'm also learning the rest of the language first as I go).
Thanks!
In C# this will throw a compiler error because C and B are not the same type with ImmutableList.
In C#, classes are not co/contravariant, these are properties of Interfaces and Delegates used via the in
and out
keywords. Remember, in C#, a List<T>
is a mutable list, and doesn't work like the immutable List[T]
in Scala.
What you can do is declare the base type for the List<T>
:
void Main()
{
var list = new List<A>();
list.Add(new B());
list.Add(new C());
}
class A { }
class B : A { }
class C : A { }
Same goes for using an interface for T
, but you can't go further than that. This will not compile:
void Main()
{
var bs = new List<B>();
var cs = new List<C>();
var result = bs.Concat(cs);
}
For more on that, see Why isn't there generic variance for classes in C# 4.0?