我有这段代码,如果遇到错误的结果并且在异常的情况下返回 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"两次?
我建议您不要在此函数中处理异常,假设它的行为正确。
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
)。
为了进一步重构这一点,我将创建另一种方法来发出 Web 请求,并使用另一种方法来解析响应。
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);
}
只需将返回移出 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;
如果可能的话,我喜欢一个单一的返回点:
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,这应该不是问题。