可以堆叠使用合并成一个使用语句吗?

时间:2013-11-06 17:52:58

标签: c# garbage-collection dispose

我有一个像这样返回的方法:

using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
    return reader.ReadToEnd();

我可以将这三种用法结合起来并具有相同的安全等级吗?

using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
    return reader.ReadToEnd();

或者因为这是一个私有范围的功能,我可以安全地返回而不使用吗?

return new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();

包含此方法的对象不是IDisposable。我对我的两个问题都没有猜测,但我对其他观点感到好奇。

2 个答案:

答案 0 :(得分:4)

对于一般情况,你不能做出这个假设。对于您的具体情况,可以进行一些合并。特别是,处理StreamReader也会关闭底层流,因为documentation for StreamReader.Close()提供了这个保证:

  

关闭StreamReader对象和基础流

(强调我的)。因此,您可以从样本中跳过中间使用块。但是,同样的保证不是从Stream到HttpResponse对象,这意味着你仍然希望保留它。所以你可以这样做:

using (var response = request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
    return reader.ReadToEnd();

此外,还有一种情况是您可以将堆叠的using块组合到一个块中。当使用块管理的所有项目具有相同类型时,您可以使用逗号分隔每个对象。例如,打开一个文件进行读取并将输出处理到另一个文件可以这样做:

using (var infile = new FileStream("infile"), outfile = new FileStream("outfile"))
{
    //...
}

答案 1 :(得分:2)

通常,您需要单独的语句以确保正确清理所有内容:

using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
    return reader.ReadToEnd();

否则,中途出现的错误可能会使资源不受干扰。例如。如果GetResponseStream()在此代码中引发异常,您最终会得到一个不受欢迎的回复:

using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
    return reader.ReadToEnd();