views:

148

answers:

6

This is a question I have asked myself many times in the past as I nested using statements 5 deep.

Reading the docs and finding no mention either way regarding other disposables instantiated within the block I decided it was a good Q for SO archives.

Consider this:

using (var conn = new SqlConnection())
{
    var conn2 = new SqlConnection();
}

// is conn2 disposed?
+3  A: 

Obviously I have the answer... ;-)

The answer is no. Only the objects in the using declaration are disposed

[Test]
public void TestUsing()
{
    bool innerDisposed = false;
    using (var conn = new SqlConnection())
    {
        var conn2 = new SqlConnection();
        conn2.Disposed += (sender, e) => { innerDisposed = true; };
    }

    Assert.False(innerDisposed); // not disposed
}

[Test]
public void TestUsing2()
{
    bool innerDisposed = false;
    using (SqlConnection conn = new SqlConnection(), conn2 = new SqlConnection())
    {
        conn2.Disposed += (sender, e) => { innerDisposed = true; };
    }
    Assert.True(innerDisposed); // disposed, of course
}
Sky Sanders
FYI: I had the answer in the clipboard before I submitted the question.
Sky Sanders
A: 

No. Check the generated IL with ILDASM or Reflector.

No Refunds No Returns
you are just too fast for me to QnA myself....
Sky Sanders
+10  A: 

No they are not. Only the set of variables explicitly listed in the using clause will be automatically disposed.

JaredPar
So you'll need to nest your using's 6 deep :-)
Eric J.
I guess you have a fan club Jared.. lol..
Sky Sanders
A: 

Only the variables within the using() will be disposed, not the actual code block. .

Stan R.
+1  A: 

No. Using causes the object in the using statement to be disposed. If you want both of your objects to be disposed, you should rewrite this as:

using (var conn = new SqlConnection())
{
    using (var conn2 = new SqlConnection())
    {
        // use both connections here...
    }
}

Or, alternatively, you can use the more succinct syntax:

using (SqlConnection conn = new SqlConnection(), conn2 = new SqlConnection())
{
    // use both connections here...
}
Reed Copsey
Note that you can write this more compactly. "using(SqlConn conn1 = new SqlConn(), conn2 = new SqlConn()) { stuff }"
Eric Lippert
Also, a `using` statement rather than a block (`using(var conn=new SqlConnection())using(var conn2=new SqlConnection()){ ... }`) will be lined up nicely in Visual Studio. It won't indent the second `using`.
Jeffrey L Whitledge
@Eric Lippert: I updated to show that option, too... @Jeffrey: I tend to not do that, as StyleCop complains if you don't use braces for each statement.
Reed Copsey
+5  A: 

If you want the exact rules for the using statement see section 8.13 of the specification. All your questions should be clearly answered there.

Eric Lippert
@eric, thanks for the reference. I posted this Q after having sussed it out with the tests in my answer more as a public service than anything else.
Sky Sanders
@Eric: care to supply a link to the spec, for those who don't know the way to MSDN?
John Saunders
http://www.bing.com/search?q=c%23+specification
Eric Lippert