7

我将尝试缩短此代码示例:

public interface IThing
{
    //...  Stuff
}

public class Thing1 : IThing
{  
}

public class Thing2 : IThing
{  
}

public interface IThingView<out T>
{
    ICollection<T> ViewAll();
}

public class ThingView<T> : IThingView<T>
{
    ICollection<T> ViewAll() { return new List<T>(); }  //  There's a big operation here
}

public interface IThingViewerFactory
{
    public IThingView<IThing> Build(string Which);
}

public class ThingViewerFactory
{
    public IThingView<IThing> Build(string Which)
    {
        if(Which.Equals("Thing1") { return new (IThingView<IThing>)new ThingViewer<Thing1>();}
        else { return new (IThingView<IThing>)new ThingViewer<Thing2>();}
    }
}

这是我在做什么的一个粗略的想法。我有许多需要查看器的事物类,它们将遵循一个通用接口。我想要一个工厂通过我传入一个带有名称的字符串来生成这些。我不断收到编译器错误抱怨:

无效方差:类型参数“T”必须在“IThingView.ViewAll()”上始终有效。“T”是协变的。

我意识到即使我让这个工作,我之后也必须做一些铸造......我很好。我意识到这种方法很可能没有必要。在这一点上,这已成为更多的骄傲/好奇心问题。

谢谢!

4

2 回答 2

11

您不能制作 covariant ICollection<T>,因为它允许您将Ts 放入其中。

您可以创建协变只读集合、逆变只写集合或不变读写集合。
你不能两者都做,否则它不会是类型安全的。

于 2011-05-26T17:45:35.080 回答
6

要扩展 SLaks 答案:
要编译您的代码,请将ViewAllfrom的返回类型更改ICollection<T>IEnumerable<T>

于 2011-05-26T17:50:37.777 回答