C#泛型,并使用来自类型化方法的非泛型版本

本文关键字:泛型 方法 类型化 版本 | 更新日期: 2023-09-27 18:26:26

我正在使用RestSharp库访问REST API。

我希望所有API请求都通过相同的方法,这样我就可以在中心位置添加头、处理错误和做其他事情。

因此,我制作了一个接受泛型Func<>的方法,它解决了我的大多数问题,但我不知道如何处理没有返回类型的情况。

private T PerformApiCall<T>(RestRequest restRequest, Func<RestRequest, IRestResponse<T>> restMethod)
{
    var response = restMethod.Invoke(restRequest);
    //handle errors
    ....
    return response.Data;
}

我这样称呼它:

var apples = PerformApiCall(new RestRequest('/api/apples'), req => Client.Execute<List<Apple>>(req));

但我遇到了一个问题,一堆API调用没有返回类型,因为它们不返回数据。所以我使用了Client.Execute(req),我得到了一个错误,说类型参数无法推断,我试图传递,但失败了,因为它无法将非泛型IRestResponse转换为类型化的。

关于如何以一种好的方式解决这个问题,有什么想法吗?

C#泛型,并使用来自类型化方法的非泛型版本

您可以尝试向PerformApiCall函数添加一个重载,该重载接受具有非泛型结果类型的Func,但不返回任何结果:

// Notice the `Func` has `IRestResponse`, not `IRestResponse<T>`
public void PerformApiCall(RestRequest restRequest,
                           Func<RestRequest, IRestResponse> restMethod)
    ...

然后,根据错误检查/逻辑的复杂程度,您可以将其移到一个单独的方法(返回响应),并从PerformApiCall:的两个重载中调用它

private T PerformRequestWithChecks<T>(RestRequest restRequest,
                                      Func<RestRequest, T> restMethod)
    where T : IRestResponse
{
    var response = restMethod.Invoke(restRequest);
    // Handle errors...
    return response;
}
// You can use it from both versions of `PerformApiCall` like so:
//
//     // From non-generic version
//     var response =
//         PerformRequestWithChecks<IRestResponse>(restRequest, restMethod);
//
//     // From generic version
//     var response =
//         PerformRequestWithChecks<IRestResponse<T>>(restRequest, restMethod);
//     return response.Data;

您遇到了编译器错误,因为将子类型视为其超类型的实例是合理的,但从另一个方向进行处理则不合理(这就是当您将调用代码更改为仅Client.Execute(req),返回非泛型时发生的情况)。

下面是一个表意文字粘贴说明:http://ideone.com/T2mQfl