.NET - 使用单个using语句替换嵌套的using语句

And*_*ite 6 .net c# nested idisposable using

如果您使用嵌套的using语句/资源遇到了一些这样的C#代码:

using (var response = (HttpWebResponse)request.GetResponse())
{
    using (var responseStream = response.GetResponseStream())
    {
        using (var reader = new BinaryReader(responseStream))
        {
            // do something with reader
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用这样的东西替换它是否安全?

using (var reader = new BinaryReader(((HttpWebResponse)request.GetResponse()).GetResponseStream()))
{
    // do something with reader
}
Run Code Online (Sandbox Code Playgroud)

上面的例子只是嵌套的一次性资源的一个例子,所以请原谅我,如果它不是完全正确的用法.我很好奇当你处理最外层的资源(在这种情况下是BinaryReader),它是否会为你递归处理它的子节点,或者你是否需要用单独的using语句显式地处理每个"层"?例如,如果您处置BinaryReader,它是否应该处理响应流,而响应流又会处理响应?考虑到最后一句话让我觉得你确实需要单独的using语句,因为没有办法保证包装器对象会处理内部对象.是对的吗?

Ken*_*rds 13

你应该只堆叠你的using语句 - 它具有你想要的效果:

using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var reader = new BinaryReader(responseStream))
{
    // do something with reader
}
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 12

您需要单独的using语句.

在你的第二个例子中,只有BinaryReader意志被处置,而不是用于构造它的对象.

为了了解原因,请查看using语句实际执行的操作.它需要你的第二个代码,并做一些相当于:

{
    var reader = new BinaryReader(((HttpWebResponse)request.GetResponse()).GetResponseStream());
    try
    {
      // do something with reader
    }
    finally
    {
        if (reader != null)
            ((IDisposable)reader).Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,或者永远不会有一个Dispose()电话.ResponseResponseStream