我试图运行这段代码,但是当我尝试检查时,存在一个问题,即对象的类型与其抽象类类型不匹配
它位于“if (handler is Handler
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;
}
}
看起来应该可以,但似乎我做错了什么
简单来说,模式匹配失败是因为泛型类型默认是不变的。即使您有
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());