[英]How can I add Interface of dervived types to a dictionary of interfaces of base type
I am trying to create a class where I can register a bunch of different handlers for requests that the application must service.我正在尝试创建一个类,我可以在其中为应用程序必须服务的请求注册一堆不同的处理程序。 The request produces a response that will be sent back to the remote.
该请求产生一个响应,该响应将被发送回远程。 I have an interface for anything that can handle the request.
我有任何可以处理请求的接口。 All requests and responses inherit from ProtoBase.
所有请求和响应都继承自 ProtoBase。 (The protobase class handles the serialization of its state into a byte array).
(protobase 类将其状态序列化为字节数组)。 The interface is below.
界面如下。
public interface IHandler<TReq, TResp>
where TReq: ProtoBase
where TResp: ProtoBase
{
TResp Handle(TReq, object origin);
}
public class Foo
{
private Dictionary<ReqType, IHandler<ProtoBase, ProtoBase>> handlers;
public Foo()
{
handlers = new Dictionary<ReqType, IHandler<ProtoBase, ProtoBase>>();
}
public void RegisterHandler(IHandler<BarRequest, BarResp> fooBarHandler)
{
handlers[ReqType.FooBar] = fooBarHandler;
}
public void Run()
{
while(true)
{
var req = GetRequest();
var handler = handlers[req.ReqType];
var resp = handler.Handle(req);
Send(resp);
}
}
}
The code above produces a compiler error上面的代码产生一个编译器错误
Cannot implicitly convert type 'IHandler<BarRequest, BarResp>' to 'IHandler<ProtoBase, ProtoBase>'.
无法将类型“IHandler<BarRequest, BarResp>”隐式转换为“IHandler<ProtoBase, ProtoBase>”。 An explicit conversion exists (are you missing a cast?)
存在显式转换(您是否缺少演员表?)
I tried playing with contravariance and covariance on the interface but it made no difference.我尝试在界面上玩逆变和协方差,但没有任何区别。
You cannot make IHandler<ProtoBase, ProtoBase>
a superclass for your specific handlers, no matter how much you play around with co- and contravariance.你不能让
IHandler<ProtoBase, ProtoBase>
成为你的特定处理程序的超类,无论你如何处理IHandler<ProtoBase, ProtoBase>
和逆变。
Why?为什么? Let's assume this were possible, then we could have the following code:
让我们假设这是可能的,那么我们可以有以下代码:
IHandler<SomeRequest, SomeResponse> specificHandler = ...;
IHandler<ProtoBase, ProtoBase> handler = specificHandler; // won't work, but let's assume it does
// Should work from a type system POV, since SomeOtherRequest also inherits from ProtoBase,
// but can't work from a logic POV, since your handler can only handle SomeRequest.
handler.Handle(new SomeOtherRequest());
For that cast to work, it would need to be IHandler<out TReq, out TResp>
, but in terms of variance, your Handle
method is only compatible with IHandler<in TReq, out TResp>
.要使该转换起作用,它需要是
IHandler<out TReq, out TResp>
,但就方差而言,您的Handle
方法仅与IHandler<in TReq, out TResp>
兼容。
So: you can't.所以:你不能。 You might need to make the type actually implement
IHandler<ProtoBase, ProtoBase>
.您可能需要使类型实际实现
IHandler<ProtoBase, ProtoBase>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.