为什么我收到“类型参数必须始终有效...”错误?
我将尝试缩短此代码示例:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法创建协变
ICollection
,因为它允许您将T
放入其中。您可以创建协变只读集合、逆变只写集合或不变读写集合。
你不能两者都做,否则它就不是类型安全的。
You cannot make a covariant
ICollection<T>
, since it allows you to putT
s 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.
扩展 SLAks 的答案:
要使代码能够编译,请将
ViewAll
的返回类型从ICollection
更改为IEnumerable
。To expand on SLaks answer:
To make your code compile, change the return type of
ViewAll
fromICollection<T>
toIEnumerable<T>
.