强制转换简单泛型对象
本文关键字:泛型 对象 简单 转换 | 更新日期: 2023-09-27 18:06:57
我创建了一个方法来简化使用HttpClient调用。它使用HttpReponse.Content.ReadAsAsync()方法。从API获得响应的结果。
这一切都很好。我的方法看起来像这样:
public static T ExecuteAPIGetRequest<T>(string url, Dictionary<string, string> parameters)
{
HttpClient client = new HttpClient();
//basic authentication
var t = new object();
string baseURL = "myurl";
//Execute request
HttpResponseMessage response = client.GetAsync(baseURL).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result;
}
else
{
return (T)t;
}
}
我的问题是,如果查询失败,它需要返回一个空类型的t。这是很好的,如果它是一个自定义类我写的,但它不工作的对象,如string或string[]。什么好主意吗?
欢呼NCBL
尝试返回default(T)
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result;
}
else
{
return default(T);
}
default将为引用类型返回null
,并为零数值int
, double
等。以及相应的自定义struct
和enum
的默认值。
Daniel注意到一个问题:如果对于引用类型你想返回默认对象而不是null,你应该定义泛型约束new T()
。现在您可以使用调用无参数构造函数实例化类型为T
的对象。完整方法如下:
public static T ExecuteAPIGetRequest<T>(string url,
Dictionary<string, string> parameters)
where T : new()
{
HttpClient client = new HttpClient();
//basic authentication
string baseURL = "myurl";
HttpResponseMessage response = client.GetAsync(baseURL).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result;
}
else
{
return new T(); //returns an instance, not null
}
}
现在您将返回引用类型的默认对象,而不是null。开放类型T
只能接受默认具有构造函数(不带参数)的类型
我可以建议您考虑这样的方法....
class Program
{
static void Main(string[] args)
{
var client = new HttpClient();
//basic authentication
string baseURL = "myurl";
var link = Link<Foo>.Create(baseURL);
var response = client.SendAsync(link.CreateRequest()).Result;
var myfoo = link.ProcessResponse(response);
}
}
public class Link<T>
{
public Uri Target { get; set; }
public static Link<T> Create(string url)
{
return new Link<T>() {Target = new Uri(url)};
}
public HttpRequestMessage CreateRequest()
{
return new HttpRequestMessage() {RequestUri = Target};
}
public T ProcessResponse(HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result;
}
else
{
return new T(); //returns an instance, not null
}
}
}
public class Foo
{
}
通过将创建链接的机制封装到静态工厂方法中,并将响应的处理封装到ProcessResponse方法中,您可以获得类似级别的可重用性,但您也可以获得重用相同HttpClient的好处。这允许你实际利用DefaultRequestHeaders,它将阻止HttpClient在它被处理时继续关闭连接。
另外,通过避免将Async调用包装在同步方法中,您可以让调用代码决定是阻塞结果还是异步处理它。当前使用. result的方式可能会在某些时候遇到死锁问题。
这种创建Link类来封装与取消引用URL相关的特定行为的技术可能非常有用。添加可用于填充URI模板的参数是很容易的。你也可以用它来处理请求正文