2016-09-13 95 views
1

这个我们的完整代码GitHub Gist我只包括我认为需要显示的问题部分。返回通用对象类型

Execute方法:

public object Execute() 
     { 
      var request = createWebRequest(); 
      request.Method = this.Method; 
      applyPostData(ref request); 

      request.ContentType = "application/json"; 
      request.UserAgent = "generic-http-dotnet-client/3.5/v1 (gzip)"; 

      var response = (HttpWebResponse)request.GetResponse(); 

      var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); 

      try 
      { 
       return JsonConvert.DeserializeObject(responseString); 
      } 
      catch (Exception) 
      { 
       return new HttpResponse { message = responseString }; 
      } 
     } 

好这部作品的一种。然而,我希望能够做的是在该方法被称为适当的对象类型之后。

var response = (MetaDataResponse)request.Execute(); 

我知道应该有使用泛型我(野生猜测),以JSON DeserializeObject回应,并将它的一些方式可能?

我最终将执行方法的返回类型更改为一个字符串,并执行此操作。

public class MetaDataRequest : HttpRequestBase 
    { 
     public MetaDataResponse MetaDataItems { get; private set; } 

     public MetaDataRequest() : base(new Uri("https://www.googleapis.com/analytics/v3/metadata/ga/columns"), "GET") 
     { 
      this.addParameter("key", "xxxx"); 
      var response = this.Execute(); 

      try 
      { 
       MetaDataItems = JsonConvert.DeserializeObject<MetaDataResponse>(response); 
      } 
      catch (Exception) 
      { 
       var resultsx = new HttpResponse { message = response }; 
      } 
     } 
    } 

哪些工作,但接缝混乱给我。注意这个项目是.Net框架3.5,我不能改变这一点。随意添加任何你能想到的其他标签。

+0

我不会在生产中使用类似的代码......看起来很笨拙的代码。 –

+3

我认为你可以像'HttpRequestBase '一样向'HttpRequestBase'添加一个类型参数并使用'JsonConvert.DeserializeObject (responseString)'和返回类型'T' – Nico

+0

同意#2。反序列化只提供该功能。试试这个,以及关于此问题的更多阅读:http://stackoverflow.com/questions/6626315/in-c-can-you-cast-one-generic-type-to-another-whost-t-parameter -is-a-subclass –

回答

1

使用通用的带班MetaDataRequest

class MetadataRequest<T>:HttpRequestBase 
{ 
    public T Execute() 
    { 
     var request = createWebRequest(); 
     request.Method = this.Method; 
     applyPostData(ref request); 

     request.ContentType = "application/json"; 
     request.UserAgent = "generic-http-dotnet-client/3.5/v1 (gzip)"; 

     var response = (HttpWebResponse)request.GetResponse(); 

     var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); 

     return JsonConvert.DeserializeObject<T>(responseString); 
    } 
} 

然后,获取对象,你可以调用方法,像这样:

MetadataResponse responseObject = (new MetadataRequest<MetadataResponse>()).Execute(); 

在这种情况下,你可以捕捉由引发的异常。 Execute(),因为它只能返回null或类型为T的实例。

编辑:您也可以使用下面的Jeremy Holovacs' answer的泛型方法。

+0

那么工作。如果我明白这一点,类名称告诉它返回类型是什么? – DaImTo

+0

是的,这是正确的。这就是泛型类和库的实现方式,允许调用者选择返回类型。 –

+0

我已经花了最近两周试图让我的头在泛型。我想我快到了。这是我没有从别人的教程中解决的第一件事。我不知道我如何与他们在一起生活了这么久。谢谢你的帮助 – DaImTo

1

首先,要点是不配置它的IDisposables,这是相当sl。。我建议这样的代替:

public T Execute<T>() 
    { 
     var request = createWebRequest(); 
     request.Method = this.Method; 
     applyPostData(ref request); 

     request.ContentType = "application/json"; 
     request.UserAgent = "generic-http-dotnet-client/3.5/v1 (gzip)"; 

     using(var response = (HttpWebResponse)request.GetResponse()) 
     using(var stream = response.GetResponseStream()) 
     using(var reader = new StreamReader(stream)) 
     { 
      try 
      { 
       var responseString = reader.ReadToEnd(); 
       return JsonConvert.DeserializeObject<T>(responseString); 
      } 
      catch (Exception ex) 
      { 
       //log something with ex 
       return default(T); 
      } 
     } 
    } 
+0

你的权利。我真的应该养成使用IDisposables的习惯。 – DaImTo

+0

顺便说一句:我不得不改变它一点我越来越“使用的语句中使用的字符串类型必须隐式转换为System.idisposable。”。只是使用streamReader然后阅读到Json的作品很好 – DaImTo

+1

哦,是的,更新。 –