2013-07-16 26 views
5

nie jestem pewien o tytule pytanie, ale tutaj jest: -Tworzenie metody wielokrotnego użytku za pomocą rodzajowych

mam kod jak: -

HttpClient client = new HttpClient();// Create a HttpClient 
client.BaseAddress = new Uri("http://localhost:8081/api/Animals");//Set the Base Address 

//eg:- methodToInvoke='GetAmimals' 
//e.g:- input='Animal' class 
HttpResponseMessage response = client.GetAsync('GetAllAnimals').Result; // Blocking call! 

if (response.IsSuccessStatusCode) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(Animal));//Animal is my Class (e.g) 
    string data = response.Content.ReadAsStringAsync().Result; 
    using (MemoryStream ms = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data))) 
    { 
     var _response = (Animal)serializer.Deserialize(ms); 
     return _response; 
    } 

} 

Działa to doskonale, teraz jeśli muszę zrobić to samo dla innej klasy powiedzieć Dog lub Cat

Co robie to: -

HttpClient client = new HttpClient();// Create a HttpClient 
    client.BaseAddress = new Uri("http://localhost:8081/api/Animals");//Set the Base Address 

    //eg:- methodToInvoke='GetAmimals' 
    //e.g:- input='Animal' class 
    HttpResponseMessage response = client.GetAsync('GetAllDogs').Result; // Blocking call! 

    if (response.IsSuccessStatusCode) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(Dog));//Animal is my Class (e.g) 
     string data = response.Content.ReadAsStringAsync().Result; 
     using (MemoryStream ms = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data))) 
     { 
      var _response = (Dog)serializer.Deserialize(ms); 
      return _response; 
     } 

    } 

Teraz chcę go zmienić na Generic klasy, coś jak ten poniżej: -

private T GetAPIData(T input,string parameters, string methodToInvoke) 
     { 
      try 
      { 

       HttpClient client = new HttpClient(); 
       client.BaseAddress = new Uri("http://localhost:8081/api/Animals"); 

       //eg:- methodToInvoke='GetAmimals' 
       //e.g:- input='Animal' class 
       HttpResponseMessage response = client.GetAsync(methodToInvoke).Result; // Blocking call! 

       if (response.IsSuccessStatusCode) 
       { 
        XmlSerializer serializer = new XmlSerializer(typeof(input)); 
        string data = response.Content.ReadAsStringAsync().Result; 
        using (MemoryStream ms = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data))) 
        { 
         var _response = (input)serializer.Deserialize(ms); 
         return _response; 
        } 

       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception(ex.Message); 
      } 
      return (T)input; 
     } 

Ale nie jestem w stanie to zrobić. Zaskoczony, nawet jak mam nazwać tę metodę?

var testData = GetAPIData(new Aminal(),null,'GetAmimals'); 

Czy to działa ... Po raz pierwszy pracuję z lekami generycznymi.

Odpowiedz

5

W definicji metody brakuje ogólnego parametru typu. Dodatkowo nie potrzebujesz pierwszego parametru (input), ponieważ go nie używasz. Podpis swojej metody powinny wyglądać następująco:

private T GetAPIData<T>(string parameters, string methodToInvoke) 

Wykorzystanie byłoby tak:

var testData = GetAPIData<Animal>(null, "GetAllAnimals"); 

Realizacja użyłby T wszędzie oryginalna metoda stosowana Dog lub Animal.

Ponadto:
Twój blok catch nie dodaje żadnej wartości. W rzeczywistości usuwa go, rzucając podstawową klasę wyjątków, której nigdy nie należy rzucać, i odrzucając oryginalny ślad stosu. Po prostu go usuń.

Ostatnia metoda będzie wyglądać następująco:

private T GetAPIData<T>(string parameters, string methodToInvoke) 
{ 
    HttpClient client = new HttpClient(); 
    client.BaseAddress = new Uri("http://localhost:8081/api/Animals"); 

    //eg:- methodToInvoke='GetAmimals' 
    //e.g:- input='Animal' class 
    HttpResponseMessage response = client.GetAsync(methodToInvoke).Result; 

    if (!response.IsSuccessStatusCode) 
     throw new InvalidOperationException("Request was not successful"); 

    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    string data = response.Content.ReadAsStringAsync().Result; 
    using (MemoryStream ms = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data))) 
    { 
     return (T)serializer.Deserialize(ms); 
    } 
} 
+1

: - Dziękuję .. miliona ton ... +1 dla wspomnieć 'Usage', dała wyraźny obraz. – Shubh

0

Przegapiłeś ogólnej definicji

private T GetAPIData<T>(string parameters, string methodToInvoke) 

i

var testData = GetAPIData<Animal>(null,'GetAmimals'); 

Twój parametr input jest bezużyteczny, więc można go usunąć.

Można również dodać type costraint:

private T GetAPIData<T>(string parameters, string methodToInvoke) where T:IAnimal 
Powiązane problemy