为什么不能推断出这些generics类型参数?

给定以下接口/类:

public interface IRequest { } public interface IHandler where TRequest : IRequest { TResponse Handle(TRequest request); } public class HandlingService { public TResponse Handle(TRequest request) where TRequest : IRequest { var handler = container.GetInstance<IHandler>(); return handler.Handle(request); } } public class CustomerResponse { public Customer Customer { get; set; } } public class GetCustomerByIdRequest : IRequest { 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? 

我只是得到’类型参数无法推断’的消息。 这是一般的generics类型推断的限制,还是有办法使这项工作?

你有约束TRequest : IRequest ,但这并不意味着可以从TRequest自动推断出TResponse 。 考虑到类可以实现多个接口, TRequest可以实现多个 IRequest类型; 您可能不会在自己的设计中执行此操作,但编译器必须在整个类层次结构中跋涉以推断该特定参数,这将非常复杂。

简而言之, Handle方法有两个generics类型参数( TRequestTResponse ),你只给它一个它实际可以使用的参数。 Inferrence仅发生在实际的类型参数上,而不是它们inheritance或实现的类型。

我认为这取决于使用情况……

在这种情况下,某些东西(你不在上面列出)是调用service.Handle(request);

如果消费类没有在它自己的声明中包含generics类型,我想你会遇到这个问题。

例如……(这不起作用)

 public class MyClass { var service = new HandlingService(); var request = new GetCustomerByIdRequest { CustomerId = 1234 }; var response = service.Handle(request); } 

这应该工作……(该类需要知道TResponse是什么)

 public class MyClass where TResponse : YOURTYPE { var service = new HandlingService(); var request = new GetCustomerByIdRequest { CustomerId = 1234 }; var response = service.Handle(request); }