C# 强制转换简单的泛型对象
我创建了一个方法来简化HttpClient调用。它使用方法HttpReponse.Content.ReadAsAsync().Result从API获取响应 这一切都很好。我的方法如下所示:C# 强制转换简单的泛型对象,c#,asp.net-web-api,dotnet-httpclient,C#,Asp.net Web Api,Dotnet Httpclient,我创建了一个方法来简化HttpClient调用。它使用方法HttpReponse.Content.ReadAsAsync().Result从API获取响应 这一切都很好。我的方法如下所示: public static T ExecuteAPIGetRequest<T>(string url, Dictionary<string, string> parameters) { HttpClient client = new HttpClien
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;
}
}
public static T executeAppigetRequest(字符串url、字典参数)
{
HttpClient=新的HttpClient();
//基本身份验证
var t=新对象();
字符串baseURL=“myurl”;
//执行请求
HttpResponseMessageResponse=client.GetAsync(baseURL).Result;
if(响应。IsSuccessStatusCode)
{
返回response.Content.ReadAsAsync().Result;
}
其他的
{
返回(T)T;
}
}
我的问题是,如果查询失败,它需要返回一个空类型的T。如果它是我编写的自定义类,这是可以的,但它不适用于string或string[]之类的对象。有什么想法吗
干杯
NCBL尝试返回默认值(T)
现在,您将返回引用类型的默认对象,而不是null。开放式<代码> t>代码>只能采用默认构造函数(不含参数)< p>的类型,我可以建议你考虑这样的一种方法…
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
{
}
类程序
{
静态void Main(字符串[]参数)
{
var client=新的HttpClient();
//基本身份验证
字符串baseURL=“myurl”;
var link=link.Create(baseURL);
var response=client.sendaync(link.CreateRequest()).Result;
var myfoo=link.ProcessResponse(response);
}
}
公共类链接
{
公共Uri目标{get;set;}
公共静态链接创建(字符串url)
{
返回新链接(){Target=newURI(url)};
}
公共HttpRequestMessage CreateRequest()
{
返回新的HttpRequestMessage(){RequestUri=Target};
}
公共T进程响应(HttpResponseMessage响应)
{
if(响应。IsSuccessStatusCode)
{
返回response.Content.ReadAsAsync().Result;
}
其他的
{
return new T();//返回一个实例,不为null
}
}
}
公开课Foo
{
}
通过将创建链接的机制封装到静态工厂方法中,并将响应处理封装到ProcessResponse方法中,您可以获得类似级别的可重用性,但也可以获得重用相同HttpClient的好处。这允许您实际利用DefaultRequestHeaders,并且在释放连接时,它将阻止HttpClient继续关闭连接
另外,通过避免将异步调用包装在sync方法中,您可以让调用代码决定是为结果阻塞还是异步处理它。您当前使用.Result的方式可能会在某个时候遇到死锁问题
这种创建链接类来封装与取消引用URL相关的特定行为的技术非常有用。添加可用于填充URI模板的参数很容易。您还可以使用它来处理请求主体。请注意:如果
T
是引用类型,则这将是null
,很可能是引用类型。如果要返回默认实例,则需要将new
约束添加到T
和returnnew T()代码>相反。@DanielHilgarth可能我遗漏了什么,但是default(T)
为基本体和自定义结构返回正确的值。我刚刚测试了double
和自定义结构。您不需要指定泛型约束,结构将始终具有无参数constructor@IlyaIvanov:我说的不是值类型,而是引用类型。对于这些,它将返回null
。但是,OP正在创建一个新实例并尝试返回该实例。在我看来,他似乎想返回一个实例,而不是null
@DanielHilgarth。非常感谢,我收到了你的评论。将更新我的答案
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
}
}
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
{
}