2016-09-13 1 views
1

Полный код для этого нам на GitHub Gist я только в том числе часть, я думаю, необходимо, чтобы показать проблему.Вернуться Родовой тип объекта

Выполнить метод:

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 }; 
      } 
     } 

Хорошо это работает вид. Однако то, что я хотел бы сделать, - это после того, как метод называется cast как соответствующий тип объекта.

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

Я знаю, что должен быть какой-то способ, возможно, с помощью дженериков (Wild угадывать) для меня 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 framework 3.5, и я не могу его изменить. Не стесняйтесь добавлять любые другие теги, о которых вы можете думать.

+0

Я бы не использовал такой код, как на производстве ... кажется, действительно неуклюжий код. –

+3

Я думаю, вы могли бы добавить параметр типа в 'HttpRequestBase', например' HttpRequestBase ', и использовать 'JsonConvert.DeserializeObject (responseString)' и возвращаемый тип 'T' – Nico

+0

Согласен с # 2. Deserialize предлагает именно эту функциональность. Попробуйте это, а также, чтобы больше узнать по этому вопросу: http://stackoverflow.com/questions/6626315/in-c-can-you-cast-one-generic-type-to-another-whos-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(); 

В этом случае, вы можете поймать исключение брошенный. Выполнить(), поскольку он может возвращать только null или экземпляр типа T.

Редактировать: вы также можете использовать общий метод, следуя Jeremy Holovacs' answer.

+0

Хорошо, что сработало. Если я это понимаю, то именем класса сообщает ему, что такое тип возврата? – DaImTo

+0

Да, это правильно. Вот как реализуются общие классы и библиотеки, позволяя вызывающему пользователю выбрать тип возврата. –

+0

Я провел последние две недели, пытаясь раздобыть дженерики. Я думаю, что я почти там. Это было первое, что я сделал сам, не справившись с чужим руководством. Я не знаю, как я жил с ними так долго. Благодарим за помощь. – DaImTo

1

Во-первых, суть не распоряжаться своим IDisposables, это довольно неряшливо. Я бы рекомендовал что-то вроде этого:

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

BTW: Мне пришлось немного изменить его. Я получаю «строковый тип, используемый в операторе using, должен быть неявно конвертируемым в System.idisposable». просто используя streamReader, а затем читаю его в Json, прекрасно работает – DaImTo

+1

О да, обновлено. –

Смежные вопросы