我想我必须遗漏一些东西,为什么我不能编译它:
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
}
答案 0 :(得分:9)
你在这里使用一个列表让事情变得更加困惑......最简单的方法是看到这种效果:
// This won't compile
Foo<Bar> fooBar = new Foo<MyBar>();
鉴于这不能编译,因此您无法将Foo<MyBar>
添加到List<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下载 - 只需搜索“差异”。
答案 1 :(得分:3)
它无法编译,因为如果您使用Foo<int>
调用方法,则调用将失败:您正在尝试为通用参数设置特定类型。
您需要的是使用var listOfFoos = new List<Foo<T>>()
,然后Add
应该有效。
(编辑:同样,如果您使用Foo<T>
,演员阵容也会有效 - 但您仍然无法在代码中假设T
是Bar
。)