Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET - Replacing nested using statements with single using statement

If you came across some C# code like this with nested using statements/resources:

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

Is it safe to replace it with something like this?

using (var reader = new BinaryReader(((HttpWebResponse)request.GetResponse()).GetResponseStream()))
{
    // do something with reader
}

The example above is just an example of nested disposable resources, so forgive me if it's not exactly correct usage. I'm curious if when you dispose the outermost resource (the BinaryReader in this case), if it will recursively dispose its children for you, or if you need to explicitly dispose each "layer" with separate using statements? E.g. if you dispose the BinaryReader, is it supposed to dispose the response stream, which in turn disposes the response? Thinking about that last sentence makes me think you actually do need the separate using statements, because there's no way to guarantee that a wrapper object would dispose of the inner object. Is that right?

like image 580
Andy White Avatar asked Oct 19 '10 23:10

Andy White


3 Answers

You should just stack your using statements - it has the desired effect you are looking for:

using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var reader = new BinaryReader(responseStream))
{
    // do something with reader
}
like image 193
Ken Richards Avatar answered Sep 22 '22 01:09

Ken Richards


You need the separate using statements.

In your second example, only the BinaryReader will get disposed, not the objects used to construct it.

In order to see why, look at what the using statement actually does. It takes your second code, and does something equivalent to:

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

As you can see, there would never be a Dispose() call on the Response or ResponseStream.

like image 28
Reed Copsey Avatar answered Sep 22 '22 01:09

Reed Copsey


FWIW, here's another way to spell your original example which may satisfy any dismay over nesting:

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

Whether the reader disposes of the stream is really a function of the reader, not the 'using'. As I recall that is often what the behavior with readers is--they take ownership of the stream and dispose of it when the reader is itself closed. But the form I've provided above should be fine.

like image 40
Curt Nichols Avatar answered Sep 21 '22 01:09

Curt Nichols