为什么我得到"类型参数必须是无效的......"错误?

The*_*TFo 7 c# generics variant factory-pattern

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

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>();}
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我正在做的一个粗略的想法.我有许多需要查看器的Thing类,它们将遵循comon界面.我希望一个工厂通过我传递一个带有名字的字符串来生成这些.我不断抱怨编译错误:

方差无效:类型参数"T"必须在"IThingView.ViewAll()"上无效.'T'是协变的.

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

谢谢!

SLa*_*aks 11

你不能做出协变ICollection<T>,因为它允许你把T它放进去.

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


Dan*_*rth 6

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