.NET - Replacing nested using statements with single using statement

后端 未结 5 794
说谎
说谎 2021-01-12 19:08

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

using (var response = (HttpWebResponse)request.GetResponse())
{
    using (         


        
相关标签:
5条回答
  • 2021-01-12 19:29

    According to the documentation, BinaryReader.Close will close the underlying stream. http://msdn.microsoft.com/en-us/library/system.io.binaryreader.close.aspx

    Also, according to the documentation for HttpWebResponse, you either have to close the underlying stream or dispose the response. http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx

    So the second example you provided would work.

    0 讨论(0)
  • 2021-01-12 19:33

    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.

    0 讨论(0)
  • 2021-01-12 19:40

    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
    }
    
    0 讨论(0)
  • 2021-01-12 19:42

    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.

    0 讨论(0)
  • 2021-01-12 19:50

    I posted this elsewhere, but separating your declarations by comma seems to treat each statement separated this way as a new declaration and disposes of them.

    using (IType1 a = new Type1(), b = new Type1()){}

    This however means your objects must be of the same type. You could call them like

    using (IDisposable a = new Type1(), b = new Type2()){}

    But then of course, you only have access to IDisposable methods, without casting the object, which is kinda dumb. So instead, I believe you can use

    using (var a = new Type1(), b = new Type2()){}

    This appears to give you the correctly typed object references allowing you access to the proper method of the allocated type, and disposes of both objects created. If anyone knows why I'm not right, please let me know because this appears to work for me? (I know this question is really old n stuff, but it's all I could find while searching for this answer myself)

    0 讨论(0)
提交回复
热议问题