我想我一定会丢失一些东西,为什么我不能编译它:
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>
中添加List<Foo<Bar>>
也就不足为奇了那么,为什么
Foo<MyBar>
不是Foo<Bar>
?因为泛型类不是协变的。通用方差仅在C#4中引入-它仅适用于接口(interface)和委托(delegate)。因此,您可以(在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下载-只需搜索“方差”即可。