Covariant和Contravariant Monadic类型ala Scala的C#列表

时间:2016-05-05 13:36:31

标签: c# list scala covariance contravariance

我是c#的新手但是对scala比较有经验,我试图模仿scala的列表类(由Cons和静态类Nil扩展)。我希望得到它所具有的类型行为,因为.NET自4.0以来一直支持协方差/逆变。请允许我表明我的意思:

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]!!!

在C#中,这将引发编译器错误,因为C和B与ImmutableList的类型不同。

似乎不是网上的例子,而且我仍然是C#的新手,所以我认为在尝试眩目之前询问C#是否能以任何方式做到这一点是明智的(我仍然是尝试但我也在学习其余的语言。)

谢谢!

1 个答案:

答案 0 :(得分:3)

  

在C#中,这将引发编译器错误,因为C和B不是   与ImmutableList相同的类型。

在C#中,类不是共变/反变,这些是通过inout关键字使用的接口和代理的属性。请记住,在C#中,List<T>可变列表,并且不像Scala中的不可变List[T]那样工作。

您可以做的是声明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 { }

使用T的界面也是如此,但你不能更进一步。这不会编译:

void Main()
{
    var bs = new List<B>();
    var cs = new List<C>();
    var result = bs.Concat(cs);
}

有关详情,请参阅Why isn't there generic variance for classes in C# 4.0?