[英]C# Generics and using the non-generic version from typed method
I'm using the RestSharp library to access a REST API. 我正在使用RestSharp库来访问REST API。
I want all the API requests to go through the same method, so I can add headers, handle errors and do other stuff in a central place. 我希望所有API请求都通过相同的方法,因此我可以添加标头,处理错误并在中心位置执行其他操作。
So I made a method that accepts a generic Func<>
and that solves most of my problems, but I don't know how to handle the case where I don't have a return type. 所以我创建了一个接受泛型
Func<>
的方法,它解决了我的大部分问题,但我不知道如何处理我没有返回类型的情况。
private T PerformApiCall<T>(RestRequest restRequest, Func<RestRequest, IRestResponse<T>> restMethod)
{
var response = restMethod.Invoke(restRequest);
//handle errors
....
return response.Data;
}
I call it like this: 我称之为:
var apples = PerformApiCall(new RestRequest('/api/apples'), req => Client.Execute<List<Apple>>(req));
But I came across a problem, a bunch of API calls don't have a return type because they don't return data. 但是我遇到了一个问题,一堆API调用没有返回类型,因为它们不返回数据。 So I used
Client.Execute(req)
and I get the error saying the type arguments cannot be inferred, I tried to pass , but that failed because it couldn't convert the non-generic IRestResponse
to the typed one. 所以我使用
Client.Execute(req)
并且我得到错误,说明无法推断类型参数,我试图通过,但是失败了因为它无法将非泛型IRestResponse
转换为键入的类型。
Any ideas on how to tackle this in a nice way? 关于如何以一种好的方式解决这个问题的任何想法?
One thing you could try is to add an overload to your PerformApiCall
function that takes a Func
with a non-generic result type, and returns nothing: 您可以尝试的一件事是向
PerformApiCall
函数添加一个重载,该函数采用具有非泛型结果类型的Func
,并且不返回任何内容:
// Notice the `Func` has `IRestResponse`, not `IRestResponse<T>`
public void PerformApiCall(RestRequest restRequest,
Func<RestRequest, IRestResponse> restMethod)
...
Then, depending on how complex your error checking/logic is, you could move it out to a separate method (which returns the response), and call it from both overloads of PerformApiCall
: 然后,根据您的错误检查/逻辑的复杂程度,您可以将其移出到单独的方法(返回响应),并从
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;
You were getting a compiler error because it is sound to treat a subtype as if it was an instance of its supertype , but it is not sound to do it in the other direction (which is what was happening when you changed your calling code to just Client.Execute(req)
, returning a non-generic). 您收到编译器错误,因为将子类型视为其超类型的实例是合理的,但是在另一个方向上执行此操作并不合适 (这是将您的调用代码更改为刚刚发生的情况)
Client.Execute(req)
,返回非泛型)。
Here's an ideone paste illustrating this: http://ideone.com/T2mQfl 这是一个ideone粘贴,说明了这一点: http ://ideone.com/T2mQfl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.