当T为集合时,如何返回类型集合.目前它返回null



当T为集合时,如何返回类型集合。目前它返回null

public static async Task<T> CallWebApi<T>(string url, string accessToken)
{
T result = default(T);
var response = await httpClient.GetAsync(url);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return result; // returns null now. When T is collection, we want to return of   
// type collection
}
}

很难为任何可能的T提供一个好的默认值。对于函数的调用者来说,默认值可能是什么也不清楚。

因此,一个好的模式是让函数的调用者自己提供默认值。这样,该函数可以与任何类型的T一起使用,而无需猜测任何可能的T的良好默认值,也不会对调用者造成意外。
public static async Task<T> CallWebApi<T>(string url, string accessToken, T defaultValue)
{
var response = await httpClient.GetAsync(url);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return defaultValue;
}
// else
//   get the content and deserialize to T, 
//   throw an exception if that doesn't work
}

调用者可以这样使用:

var result = await CallWebApi<Model[]>(url, accessToken, Array.Empty<Model>());
可以说,这仍然太复杂了。如果API返回一个空数组怎么办?如何知道空数组是默认值还是实际的API响应?对于可空引用类型,不会以这种方式丢失信息的类型安全模式只需:
public static async Task<T?> CallWebApi<T>(string url, string accessToken) where T: class 
{
var response = await httpClient.GetAsync(url);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return null;
}
}

并且调用者不能将T?作为T的值而不首先检查它是否为null,这意味着他们不会意外地遇到NullReferenceExceptions或其他此类设计问题。

我个人会提供默认值factory parameter:

static async Task<T> CallWebApi<T>(string url, string accessToken, Func<T> defaultFactory = default)
{
var response = await new HttpClient().GetAsync(url);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return defaultFactory is null
? default
: defaultFactory();
}
return default;
}

或者只是默认值本身:

static async Task<T> CallWebApi<T>(string url, string accessToken, T defaultValue = default)
{
...
}

让用户写一些冗长但清晰的代码。

否则,你可以尝试检查类型是否实现了IEnumerable(见此答案),如果它有无参数的变量(见此答案),并排除一些"角落情况"。如string(即IEnumerable<char>),并决定如何处理集合接口(如IList<T>-这里您需要决定基本集合将使用什么,并通过Type.MakeGenericType()创建一些反射泛型魔法)。

最新更新