2013-04-02 3 views
3

HttpClient 호출 사용을 단순화하기 위해 만든 메서드가 있습니다. 그것은 API로부터 응답을 얻기 위해 HttpReponse.Content.ReadAsAsync(). Result 메서드를 사용한다.간단한 일반 개체 캐스팅

이 모든 것이 정상적으로 작동합니다. 쿼리는 사용자 정의 클래스 내가 쓴 그 경우는 괜찮 T.의 빈 유형을 반환해야 실패하지만, 경우

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

내 질문에, 그것은 작동하지 않습니다됩니다 : 내 방법은 다음과 같이 보입니다 string 또는 string []과 같은 객체. 어떤 아이디어?

건배

NCBL

답변

7

시도는 default(T)

if (response.IsSuccessStatusCode) 
{ 
    return response.Content.ReadAsAsync<T>().Result; 
} 
else 
{ 
    return default(T); 
} 

default는 참조 유형 null를 반환합니다 반환, 및 사용자 정의에 대한 숫자 값 int, double, 등 및 해당 기본값을 0으로 structenum.

다니엘은 친절하게 하나의 문제를 언급 : 참조 유형은 기본 객체하지 을 반환하려는 경우, 당신은 일반적인 제약 new T()을 정의해야합니다. 이제 매개 변수가없는 생성자에 대한 호출을 사용하여 T 유형의 객체를 인스턴스화 할 수 있습니다. 전체 방법은 다음과 같습니다.

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

이제 null이 아닌 참조 유형에 대한 기본 객체를 반환합니다. 생성의 메커니즘을 캡슐화함으로써에만 매개 변수없이 기본

+1

참고 : 'T'가 참조 유형 인 경우 'null'이되며, 가장 가능성이 큽니다. 기본 * 인스턴스 *를 반환하려면'T'에'new' 제약 조건을 추가하고 대신에'return new T();를 써야합니다. –

+0

감사합니다 일리아 이바노프, 치료를 한! 완벽 해. – ncbl

+0

@DanielHilgarth 아마도 뭔가를 놓쳤 겠지만,'default (T)'는 프리미티브와 커스텀 구조체에 대한 올바른 값을 반환합니다. 방금'double'과 custom 구조체를 테스트했습니다.당신은 일반적인 제약 조건을 지정할 필요가 없습니다. 구조체는 항상 매개 변수없는 생성자를가집니다. –

0

나는이 같은 접근 방식을 고려 제안을 만들 수에 의해 생성자가 형식을 취할 수있는 개방형 T ....

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 
{ 

} 

정적 팩토리 메소드로의 링크와 ProcessResponse 메소드로의 응답 처리와 같은 수준의 재사용 가능성을 얻을 수 있지만 동일한 HttpClient 재사용의 이점도 얻을 수 있습니다. 이를 통해 DefaultRequestHeaders를 실제로 활용할 수 있으며 HttpClient가 처리가 중단되면 연결을 계속 유지하지 않습니다.

또한 동기화 메서드 내에서 비동기 호출을 래핑하지 않으므로 호출 코드가 결과를 차단할지 비동기 적으로 처리할지 결정할 수 있습니다. 현재 사용중인 방식으로 어느 시점에서 교착 상태 문제가 발생할 가능성이 있습니다. 결과.

URL 역 참조와 관련된 특정 동작을 캡슐화하기위한 링크 클래스를 만드는이 기술은 매우 유용 할 수 있습니다. URI 템플릿을 채우는 데 사용할 수있는 매개 변수를 쉽게 추가 할 수 있습니다. 요청 본문을 처리 할 때도 사용할 수 있습니다.