微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在期望抽象父类型的地方使用子类型

如何解决如何在期望抽象父类型的地方使用子类型

这可能更多是协方差/相反的问题。但是我有以下课程:

public interface IoUtputPort<in TUseCaseResponse>
{
    void Handle(TUseCaseResponse response);
}

//Abstract parent
public abstract class Response
{
}

//Concrete child
public class GenericResponse : Response
{
}

internal class MockPresenter<TResponse> : IoUtputPort<TResponse> where TResponse : Response
{
    public void Handle(TResponse response)
    {
    }
}

public class LocationStore
{
    public void DoThing(IoUtputPort<Response> outputPort)
    {
    }
}

想法是LocationStore应该能够接受具有至少从IoUtputPort继承的泛型类型的Response对象

然后我尝试调用类似于以下内容函数

var genericPresenter = new MockPresenter<GenericResponse>();
var store = new LocationStore();

store.DoThing(genericPresenter);

但是编译器抱怨Argument 1: cannot convert from 'MockPresenter<GenericResponse> to 'IoUtputPort<Response>'

即使我从IoUtputPort删除了逆变修饰符,我仍然会遇到相同的错误。我在这里可能会遗漏一些很明显的东西,但是感觉有点卡住了。如何设计我的DoThing方法以接受可以具有可以从IoUtputPort继承的任何类型的Response

将泛型作为类型参数传递给LocationStore是不可行的,因为同一实例需要能够通过多个不同的输出端口调用DoThing

解决方法

简单的解决方案是使DoThing通用:

public void DoThing<TResponse>(IOutputPort<TResponse> outputPort) where TResponse : Response
{
}

这使它可以编译,并有望提供所需的功能。

关于为什么不允许您的设计,请考虑以下几点:

public class OutputPort<T>: IOutputPort<T>
{
    private List<T> _innerList;

    public void Handle(T response)
    {
        _innerList.Add(response);
    }
}

现在,如果TGenericResponse,并且您将能够将其投射到IOutputPort<Response>上,那么您就可以向Response添加List<GenericResponse>希望这很清楚为什么不允许这样做。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。