为什么我收到“类型参数必须始终有效...”错误?

发布于 2024-11-10 02:27:23 字数 1048 浏览 4 评论 0原文

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

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

这是我正在做的事情的粗略想法。我有许多需要查看器的 Thing 类,该查看器将遵循通用界面。我希望工厂通过我传入带有名称的字符串来生成这些。我不断收到编译器错误抱怨:

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

我意识到即使我能做到这一点,之后我还得做一些选角……我对此很满意。我意识到这种方法很可能没有必要。在这一点上,这已经成为一个更多的骄傲/好奇心问题。

谢谢!

I'll attempt to shorten this code example:

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

That's a rough idea of what I'm doing. I have a number of Thing classes that require a viewer, which will follow a comon interface. I'd like a factory to generate these by me passing in a string with the name. I keep getting a compiler error complaining:

Invalid variance: The type parameter 'T' must be invariantly valid on 'IThingView.ViewAll()'. 'T' is covariant.

I realize even if I get this to work, I'll have to do some casting afterwards... I'm fine with that. And I realize this approach is more than likely not necessary. At this point this has become more of a pride/curiosity issue.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神爱温柔 2024-11-17 02:27:23

您无法创建协变 ICollection,因为它允许您将 T 放入其中。

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

You cannot make a covariant ICollection<T>, since it allows you to put Ts into it.

You can make a covariant read-only collection, a contravariant write-only collection, or an invariant read-write collection.
You can't do both, or it wouldn't be typesafe.

ぇ气 2024-11-17 02:27:23

扩展 SLAks 的答案:
要使代码能够编译,请将 ViewAll 的返回类型从 ICollection 更改为 IEnumerable

To expand on SLaks answer:
To make your code compile, change the return type of ViewAll from ICollection<T> to IEnumerable<T>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文