2014-01-17 59 views
1

我有這樣的代碼,如果壞的結果遇到在例外的情況下返回null:我該如何重構此代碼以不返回null兩次?

private JArray GetRESTData(string uri) 
{ 
    try 
    { 
     var webRequest = (HttpWebRequest)WebRequest.Create(uri); 
     var webResponse = (HttpWebResponse)webRequest.GetResponse(); 
     if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0)) 
     { 
      var reader = new StreamReader(webResponse.GetResponseStream()); 
      string s = reader.ReadToEnd(); 
      return JsonConvert.DeserializeObject<JArray>(s); 
     } 
     MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode)); 
     return null; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
     return null; 
    } 
} 

...但它聞起來有點腐臭。有沒有辦法我可以重構這個不調用「返回null」兩次?

+2

添加最終塊返回null那裏,從刪除這兩個嘗試和catch塊 – Miller

+1

不使用「使用塊」任何理由webResponse.GetResponseStream()當你有一個不好的連接時,它會處理這個對象。 – ACS

+2

這段代碼有比兩個'return null'更大的問題。它吃任意的異常,它將錯誤顯示代碼與業務邏輯混合在一起,它不會處理它的資源。在查看瑣事之前解決大問題。 –

回答

4

我建議你不要在這個函數中處理異常,假設它的行爲正確。

private JArray GetRESTData(string uri) 
{ 
    var webRequest = (HttpWebRequest)WebRequest.Create(uri); 
    var webResponse = (HttpWebResponse)webRequest.GetResponse(); 

    var reader = new StreamReader(webResponse.GetResponseStream()); 
    string s = reader.ReadToEnd(); 

    return JsonConvert.DeserializeObject<JArray>(s); 
} 

我刪除了StatusCode檢查,因爲HttpWebResponse類都已經拋出一個異常,如果它不是一個有效的狀態代碼。

該方法的責任應該是獲取其餘數據,而不是處理用戶交互(MessageBox)。

爲了進一步重構,我將使另一種方法來進行網絡請求,另一種方法來解析響應。

private JArray GetRESTData(string uri) 
{ 
    var json = ReadFromUri(uri); 

    return JsonConvert.DeserializeObject<JArray>(json); 
} 

private string ReadFromUri(string uri) 
{ 
    using (var webRequest = (HttpWebRequest)WebRequest.Create(uri)) 
    using (var webResponse = (HttpWebResponse)webRequest.GetResponse()) 
    using (var reader = new StreamReader(webResponse.GetResponseStream())) 
    { 
     return reader.ReadToEnd(); 
    } 
} 

要使用此方法:

try 
{ 
    var myArray = GetRESTData("http://someservice.com/bananabread"); 
} 
catch (WebException exception) 
{ 
    MessageBox.Show("Some exception happened: {0}", exception); 
} 
2

就移動回了try/catch塊的

try 
{ 
    var webRequest = (HttpWebRequest)WebRequest.Create(uri); 
    var webResponse = (HttpWebResponse)webRequest.GetResponse(); 
    if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0)) 
    { 
     var reader = new StreamReader(webResponse.GetResponseStream()); 
     string s = reader.ReadToEnd(); 
     return JsonConvert.DeserializeObject<JArray>(s); 
    } 
    MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));  
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 

} 
return null; 
2

我喜歡喜歡一個返回點,如果可能的話

private JArray GetRESTData(string uri) 
{ 
    JArray ret = null; // single return value, declared outside of try/catch 
    try 
    { 
     var webRequest = (HttpWebRequest)WebRequest.Create(uri); 
     var webResponse = (HttpWebResponse)webRequest.GetResponse(); 
     if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0)) 
     { 
      var reader = new StreamReader(webResponse.GetResponseStream()); 
      string s = reader.ReadToEnd(); 
      ret = JsonConvert.DeserializeObject<JArray>(s); 
     } 
     MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode)); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
    return ret; 
} 

注:在這個簡單的例子,這大概就夠了。在更復雜的功能中,如果已經構建但處於無效狀態,則可能需要在異常處理程序內將ret設置爲null。但是,如果您使用RAII,這應該不是真正的問題。