如何在需要抽象父类型的地方使用子类型
How to use child type where abstract parent type is expected
这可能更像是一个 covariance/contravariance 问题。但我有以下 类:
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
应该能够接受具有至少从 Response
继承的泛型类型的 IOutputPort
对象
然后我尝试调用我的函数类似于:
var genericPresenter = new MockPresenter<GenericResponse>();
var store = new LocationStore();
store.DoThing(genericPresenter);
但是编译器抱怨 Argument 1: cannot convert from 'MockPresenter<GenericResponse> to 'IOutputPort<Response>'
即使我从 IOutputPort
中删除逆变修饰符,我仍然会遇到同样的错误。我可能在这里遗漏了一些非常明显的东西,但我感觉有点卡住了。我如何设计我的 DoThing
方法来接受可以具有从 Response
继承的任何类型的 IOutputPort
?
将泛型作为类型参数传递给 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);
}
}
现在如果 T
是 GenericResponse
并且您可以将其转换为 IOutputPort<Response>
突然您可以将 Response
添加到 List<GenericResponse>
希望清楚为什么不允许这样做。
这可能更像是一个 covariance/contravariance 问题。但我有以下 类:
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
应该能够接受具有至少从 Response
IOutputPort
对象
然后我尝试调用我的函数类似于:
var genericPresenter = new MockPresenter<GenericResponse>();
var store = new LocationStore();
store.DoThing(genericPresenter);
但是编译器抱怨 Argument 1: cannot convert from 'MockPresenter<GenericResponse> to 'IOutputPort<Response>'
即使我从 IOutputPort
中删除逆变修饰符,我仍然会遇到同样的错误。我可能在这里遗漏了一些非常明显的东西,但我感觉有点卡住了。我如何设计我的 DoThing
方法来接受可以具有从 Response
继承的任何类型的 IOutputPort
?
将泛型作为类型参数传递给 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);
}
}
现在如果 T
是 GenericResponse
并且您可以将其转换为 IOutputPort<Response>
突然您可以将 Response
添加到 List<GenericResponse>
希望清楚为什么不允许这样做。