2016-09-13 91 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

哦,是的,更新。 –