使用通用接口约束时的协方差/逆差异难题
public interface IShape{} public class Rectangle : IShape{} public class Base{} public class Derived : Base{} public interface IFoo where T : IShape where U : Base { T Convert(U myType); } public class MyFoo : IFoo { public Rectangle Convert(Derived myType) { throw new NotImplementedException(); } } class Program { static void Main(string[] args) { IFoo hmm = new MyFoo(); } }
鉴于上面的代码,编译器无法确定如何将类型MyFoo
分配给IFoo
MyFoo
IFoo
,可能是因为U
被设置为out意味着它可以接受更少的派生。 但是, Derived
比Base
更加派生,因此会生成编译器错误。
这个例子是设计的,但我们正在处理的实现是从工厂返回MyFoo
实现。
尽管U
用作参数,但在尝试将其分配给通用接口时它也是输出,但我无法在此处使用out
关键字。 我们怎么能解决这个问题呢?
您的IFoo界面在这种用法中似乎是错误的,它应该是:
public interface IFoo
随着U
出局。 请记住, out
generics类型参数意味着它可以“向外”变化。 也就是说,您可以隐式地将类型扩展为更宽的类型。 但是,意味着您可以隐式地将“内部”类型缩小为更具体的类型。 当然,这些只是粗略的类比。
因此,在分配hmm
的情况下,您隐式尝试将U
的接口generics类型参数从Derived
扩展为Base
,但接口声明它正在缩小( in
):
IFoo hmm = new MyFoo();
所以它无法进行隐式转换。 如果你真的希望能够隐式地扩展这个接口,那么第二个类型的参数应该是out
而不是in
。
更新:在您的评论之后,我发现最大的难题是您希望它既可以进出也不可能因为它是一个逆变输入,您不能将该接口共同分配给IFoo
,不幸的是。
您需要围绕无法分配给IFoo
的事实进行编码IFoo
或者您可以做的是创建Foo:
public class MyFoo : IFoo
然后在实现内部转换为Rectangle
。 最重要的是你不能在同一类型参数上同时具有协方差和逆变。
这有意义吗?
可以将Base转换为Rectangle的东西也会将Derived转换为IShape。 但是,可以将Derived转换为Rectangle的东西可能无法对Base执行任何有用的操作。 您正确地确定了第二个参数的协方差说明符需要“in”,但是然后尝试以与它实际支持的方式相反的方式使用协方差。
上述就是C#学习教程:使用通用接口约束时的协方差/逆差异难题分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/942806.html