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

发布于 2024-09-04 18:28:31 字数 1058 浏览 1 评论 0原文

给定以下接口/类:

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?

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

Given the following interfaces/classes:

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; }
}

Why can't the compiler infer the correct types, if I try and write something like the following:

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?

I just get the 'type arguments cannot be inferred' message. Is this a limitation with generic type inference in general, or is there a way to make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

看春风乍起 2024-09-11 18:28:31

您具有约束 TRequest : IRequest,但这并不意味着可以从 TRequest 自动推断出 TResponse。考虑到类可以实现多个接口,并且 TRequest 可以实现几种 IRequest 类型;您可能不会在自己的设计中这样做,但是对于编译器来说,必须费力地遍历整个类层次结构来推断该特定参数会非常复杂。

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

You have the constraint TRequest : IRequest<TResponse>, but that doesn't mean that TResponse can be automatically inferred from TRequest. Consider that classes can implement multiple interfaces and TRequest may implement several IRequest<TResponse> types; you may not be doing this in your own design, but it would be pretty complicated for the compiler to have to trudge through the entire class hierarchy to infer that particular parameter.

Long story short, the Handle method takes two generic type parameters (TRequest and TResponse) and you're only giving it one that it can actually use. Inferrence only happens on the actual type arguments, not the types that they inherit or implement.

尐偏执 2024-09-11 18:28:31

我认为这取决于用法...

在这种情况下,某些东西(您没有在上面列出)正在调用 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);
}

I think this depends on the usage...

In this case, something (you don't list it above) is calling service.Handle(request);

If the consuming class does not include the generic type in it's own declaration, I think you will run into this problem.

For example... (this won't work)

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

This should work... (the class needs to know what TResponse is)

public class MyClass<TResponse> where TResponse : YOURTYPE
{
     var service = new HandlingService();
     var request = new GetCustomerByIdRequest { CustomerId = 1234 };
     var response = service.Handle(request);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文