4

给定以下接口/类:

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?

我只是收到“无法推断类型参数”消息。这通常是泛型类型推断的限制,还是有办法使它工作?

4

2 回答 2

8

您有约束TRequest : IRequest<TResponse>,但这并不意味着TResponse可以从TRequest. 考虑类可以实现多个接口并且TRequest可以实现多种 IRequest<TResponse>类型;您可能不会在自己的设计中这样做,但编译器必须在整个类层次结构中艰难地推断该特定参数会非常复杂。

长话短说,该Handle方法采用两个泛型类型参数(TRequestTResponse),而您只给它一个它可以实际使用的参数。推断只发生在实际的类型参数上,而不是它们继承或实现的类型。

于 2010-06-07T14:23:32.043 回答
-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);
}
于 2010-06-07T14:26:26.250 回答