c# - C# 中 Scala 的列表的协变和逆变 Monadic 类型

标签 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# 是否可以以任何方式做到这一点是明智的(我仍在尝试,但我'我也会先学习该语言的其余部分)。

谢谢!

最佳答案

In C# this will throw a compiler error because C and B are not the same type with ImmutableList.

在 C# 中,类不是协变/逆变,这些是通过 in 使用的接口(interface)和委托(delegate)的属性。和out关键词。请记住,在 C# 中,List<T>是一个可变列表,并且不像不可变的 List[T] 那样工作。在 Scala 中。

您可以做的是声明 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 的接口(interface)也是如此,但你不能走得更远。这不会编译:

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?

关于c# - C# 中 Scala 的列表的协变和逆变 Monadic 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37052109/

相关文章:

python - 为什么此代码会更改两个列表(id 不相同)?

scala - Scala中单例对象的解释

c# - Ninject 拦截代理类与非空构造函数通过 caSTLe 动态代理

c# - 如何正确使用 SPServiceApplication 集合?

asp.net-mvc - ASP.NET MVC获取下拉列表值

c++ - 遍历对列表的 vector

Scala 条件编译

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

c# - 团结 : Error Parsing JSON from Remote Source

c# - 将日期转换为字符串格式 yyyy-mm-dd HH :MM:SS - C#