如何重构此代码以不返回两次 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"两次?

我建议您不要在此函数中处理异常,假设它的行为正确。

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,这应该不是问题。

相关内容

  • 没有找到相关文章

最新更新