通用集合冲突

时间:2012-02-08 23:44:29

标签: c# generics covariance

这是我重建这种情况的最佳尝试。

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的集合。这是协方差/逆变问题吗?

3 个答案:

答案 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();
    }
}