这是我重建这种情况的最佳尝试。
public interface IFoo
{
}
public class Foo : IFoo { }
public class Bar : IFoo { }
public class CollectionOf<T> : List<IFoo>
{
}
public class Bars : CollectionOf<Bar>
{
}
public class Test
{
public void Test()
{
CollectionOf<IFoo> bars = new Bars();
}
}
编译器抱怨实例化。 Bars是IFoos的集合。这是协方差/逆变问题吗?
答案 0 :(得分:4)
是
想一想; bars
应该能够合法地保存任何实现IFoo
的类型的对象。但是,Bars
类型的对象只能 保存Bar
类型的对象。
使用你的代码这是允许的,这显然是错误的。
CollectionOf<IFoo> bars = new Bars();
bars.Add( new Foo() ); // Uh oh!
这将有效地打破通过仿制药提供给你的类型安全。
答案 1 :(得分:2)
是的。
如果允许这样做,只要它实现了IFoo
接口,您就可以将任何对象放入该集合中,但这对于集合来说是不安全的。
让我说明一下:
var b = new Bars();
CollectionOf<IFoo> bars = b;
bars.Add(Dummy); // implements IFoo, but does not descend from Bar
此时,b
包含哪些内容? Dummy
类型的对象?那将是不好的,因此首先不允许这样做。
答案 2 :(得分:1)
修复,如果有一个将取决于它不适合你。我可以通过两种方式编写示例,使用IEnumerable或将CollectionOf定义为具有out泛型修饰符的接口。无论是否为您解决问题我都不知道:
public interface IFoo { }
public class Foo : IFoo { }
public class Bar : IFoo { }
public interface CollectionOf<out T> : IEnumerable<IFoo> { }
public class Bars : CollectionOf<Bar> { }
public class Test
{
public void Test()
{
IEnumerable<IFoo> bars1 = new Bars();
CollectionOf<IFoo> bars2 = new Bars();
}
}