C# 泛型匹配抽象类类型时出现的问题

问题描述 投票:0回答:1

我试图运行这段代码,但是当我尝试检查时,存在一个问题,即对象的类型与其抽象类类型不匹配

它位于“if (handler is Handler h)”这一行


void Main()
{
    var requestHandler = new RequestHandler();
    var result = requestHandler.Handle(new GetAge());
    Console.WriteLine(result);
}


public interface IRequest<T> { }

public class GetAge : IRequest<int> { }

public interface IHandler {}

public abstract class Handler<TRequest, TResponse> : IHandler where TRequest : IRequest<TResponse>
{
    public TResponse Handle(IRequest<TResponse> request)
    {
        return Handle((TRequest)request);
    }

    protected abstract TResponse Handle(TRequest requst);
}

public class GetAgeHandler : Handler<GetAge, int>
{
    protected override int Handle(GetAge request)
    {
        return 20;
    }
}

public class RequestHandler
{
    public Dictionary<Type, IHandler> requestHandlers = new()
    {
        [typeof(GetAge)] = new GetAgeHandler()
    };

    public T Handle<T>(IRequest<T> request)
    {
        var handler = requestHandlers[request.GetType()];
        if (handler is Handler<IRequest<T>, T> h)
        {
            return h.Handle(request);
        }
        return default;
    }
}

看起来应该可以,但似乎我做错了什么

c# .net oop generics abstract-class
1个回答
0
投票

简单来说,模式匹配失败是因为泛型类型默认是不变的。即使您有

Handler<GetAge, int>
,也不认为与
Handler<IRequest<int>, int>
兼容。如果泛型类型是协变或逆变,那么这是允许的,但在这种特定情况下,这是不可能的。

解决此问题的一种方法是定义 Handle 方法,如下所示:

public TResponse Handle<TRequest, TResponse>(TRequest request)
    where TRequest : IRequest<TResponse>
{
    var handler = requestHandlers[request.GetType()];
    if (handler is Handler<TRequest, TResponse> h)
    {
        return h.Handle(request);
    }
    return default(TResponse);
}

你会这样称呼它:

var result = requestHandler.Handle<GetAge, int>(new GetAge());
© www.soinside.com 2019 - 2024. All rights reserved.