给出以下接口/类:
public interface IRequest<TResponse> { }
public interface IHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
TResponse Handle(TRequest request);
}
public class HandlingService
{
public TResponse Handle<TRequest, TResponse>(TRequest request)
where TRequest : IRequest<TResponse>
{
var handler = container.GetInstance<IHandler<TRequest, TResponse>>();
return handler.Handle(request);
}
}
public class CustomerResponse
{
public Customer Customer { get; set; }
}
public class GetCustomerByIdRequest : IRequest<CustomerResponse>
{
public int CustomerId { get; set; }
}
如果我尝试编写如下内容,为什么编译器无法推断出正确的类型:
var service = new HandlingService();
var request = new GetCustomerByIdRequest { CustomerId = 1234 };
var response = service.Handle(request); // Shouldn't this know that response is going to be CustomerResponse?
我只是得到'无法推断的类型参数'消息。这是一般的泛型类型推断的限制,还是有办法使这个工作?
答案 0 :(得分:8)
您有约束TRequest : IRequest<TResponse>
,但这并不意味着TResponse
可以从TRequest
自动推断出来。考虑到类可以实现多个接口,TRequest
可以实现几个 IRequest<TResponse>
类型;您可能不会在自己的设计中执行此操作,但编译器必须在整个类层次结构中跋涉以推断该特定参数,这将非常复杂。
长话短说,Handle
方法需要两个泛型类型参数(TRequest
和TResponse
)而你只能给它一个它可以实际使用。 Inferrence只发生在实际类型参数上,而不是它们继承或实现的类型。
答案 1 :(得分:-1)
我认为这取决于使用情况......
在这种情况下,某些内容(您不在上面列出)正在调用service.Handle(request);
如果消费类没有在其自己的声明中包含泛型类型,我认为你会遇到这个问题。
例如......(这不起作用)
public class MyClass
{
var service = new HandlingService();
var request = new GetCustomerByIdRequest { CustomerId = 1234 };
var response = service.Handle(request);
}
这应该有用......(班级需要知道什么是TResponse)
public class MyClass<TResponse> where TResponse : YOURTYPE
{
var service = new HandlingService();
var request = new GetCustomerByIdRequest { CustomerId = 1234 };
var response = service.Handle(request);
}