简体   繁体   English

如何将派生类型的接口添加到基类型的接口字典中

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM