gpt4 book ai didi

c# - 使用通用接口(interface)约束时的协变/逆变难题

转载 作者:行者123 更新时间:2023-11-30 18:04:29 25 4
gpt4 key购买 nike

    public interface IShape{}

public class Rectangle : IShape{}

public class Base{}

public class Derived : Base{}

public interface IFoo<out T, in U>
where T : IShape
where U : Base
{
T Convert(U myType);
}

public class MyFoo : IFoo<Rectangle, Derived>
{
public Rectangle Convert(Derived myType)
{
throw new NotImplementedException();
}
}

class Program
{
static void Main(string[] args)
{
IFoo<IShape, Base> hmm = new MyFoo();
}
}

鉴于上述代码,编译器无法确定如何分配类型 MyFooIFoo<IShape, Base> ,大概是因为 U设置为 out 意味着它可以接受较少的派生。然而,Derived嗯,比Base更派生,因此会产生编译错误。

这个例子是人为设计的,但我们正在处理的实现是 MyFoo将从工厂退回。

尽管U用作参数,它也是尝试将其分配给通用接口(interface)时的输出,但我无法使用 out关键字在这里。我们如何解决这个问题?

最佳答案

你的IFoo接口(interface)这个用法好像不对,应该是:

public interface IFoo<out T, **out** U>

随着 U 的出现。请记住,out 泛型类型参数意味着它可以“向外”变化。也就是说,您可以将类型隐式扩展为更宽的类型。但是, In 意味着您可以隐式地将类型“向内”缩小为更具体的类型。当然,这些只是粗略的类比。

因此,在分配 hmm 的情况下,您正在隐式尝试将 U 的接口(interface)泛型类型参数从 Derived 扩大到 Base,但接口(interface)声明它正在缩小(in):

IFoo<IShape, Base> hmm = new MyFoo();

所以它不能进行隐式转换。如果您真的希望能够隐式扩展此接口(interface),则第二个类型参数应为 out 而不是 in

更新:在你的评论之后,我发现最大的困境是你希望它既进又出,这实际上是不可能的因为它是逆变输入,你不能将接口(interface)协变地分配给 IFoo<IShape, Base> ,很遗憾。

您要么需要围绕无法分配给 IFoo<IShape,Base> 的事实进行编码,要么您可以将 Foo 创建为:

public class MyFoo : IFoo<Rectangle, Base>

然后在执行中转换为 Rectangle。最主要的是您不能在同一类型参数上同时具有协变和逆变。

这有意义吗?

关于c# - 使用通用接口(interface)约束时的协变/逆变难题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6126741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com