一般集合冲突

本文关键字:冲突 集合 | 更新日期: 2023-09-27 18:23:46

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

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

编译器对实例化进行了抱怨。酒吧是IFoos的集合。这是协方差/反方差问题之一吗?

一般集合冲突

是。

想一想;bars应该能够合法地保存实现IFoo的任何类型的对象。但是,Bars类型的对象只能包含Bar类型的对象。

使用您的代码,这是允许的,这显然是错误的。

CollectionOf<IFoo> bars = new Bars();
bars.Add( new Foo() );  // Uh oh!

这将有效地破坏通过泛型提供给您的类型安全性。

是的。

如果允许的话,您可以将任何对象放置到该集合中,只要它实现了IFoo接口,但这对集合来说是不安全的。

让我举例说明:

var b = new Bars();
CollectionOf<IFoo> bars = b;
bars.Add(Dummy); // implements IFoo, but does not descend from Bar

在这一点上,b包含什么?Dummy类型的对象?这将是糟糕的,因此这是不允许的。

修复方法(如果有)将取决于不适合您的是什么。我可以用两种方式编译您的示例,要么使用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();
    }
}