c# – 为什么不能将受约束的开放泛型类型转换为约束类型?

我想我必须遗漏一些东西,为什么我不能编译这个:

class Foo<T> where T : Bar
{
    T Bar;
}

abstract class Bar
{ }

class MyBar : Bar
{ }

static void Main(string[] args)
{
    var fooMyBar = new Foo<MyBar>();
    AddMoreFoos(fooMyBar);
}

static void AddMoreFoos<T>(Foo<T> FooToAdd) where T : Bar
{
    var listOfFoos = new List<Foo<Bar>>();
    listOfFoos.Add(FooToAdd); //Doesn't compile
    listOfFoos.Add((Foo<Bar>)FooToAdd); //doesn't compile
}
最佳答案
你在这里使用列表让事情变得比他们需要的更混乱……最容易看到效果:

// This won't compile
Foo<Bar> fooBar = new Foo<MyBar>();

鉴于这不能编译,因此您不能添加Foo< MyBar>就不足为奇了.到列表< Foo< Bar>>

那么为什么不是Foo< MyBar>一个Foo< Bar>?因为泛型类不是协变的.

通用方差仅在C#4中引入 – 它仅适用于接口和委托.所以你可以(在C#4中)做:

IEnumerable<MyBar> x = new List<MyBar>();
IEnumerable<Bar> y = x;

但你做不到:

IList<MyBar> x = new List<MyBar>();
IList<Bar> y = x;

我有一个关于方差的讨论,你可以从NDC 2010 video site下载 – 只需搜索“方差”.

转载注明原文:c# – 为什么不能将受约束的开放泛型类型转换为约束类型? - 代码日志