10

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?
Sky Sanders
  • 36,396
  • 8
  • 69
  • 90

7 Answers7

15

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

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
6

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
  • 36,396
  • 8
  • 69
  • 90
  • FYI: I had the answer in the clipboard before I submitted the question. – Sky Sanders Feb 23 '10 at 15:49
  • I think it is technically possible for that thread to somehow get suspended such that `SqlConnection.Dispose()` would get called by `Component.Finalizer()` between the `conn2` variable going out of scope and your `Assert` line. There is a race condition here, is there not? – binki Feb 11 '14 at 19:37
4

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
  • 647,829
  • 179
  • 1,238
  • 2,067
  • @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 Feb 17 '10 at 23:02
  • 2
    @Eric: care to supply a link to the spec, for those who don't know the way to MSDN? – John Saunders Feb 17 '10 at 23:39
2

No, it doesn't work, conn2 will not be disposed. Note that multiples using are the only situation where I allow not using brackets for more lisibility :

        using (var pen = new Pen(color, 1))
        using (var brush = new SolidBrush(color))
        using (var fontM60 = new Font("Arial", 15F, FontStyle.Bold, GraphicsUnit.Pixel))
        using (var fontM30 = new Font("Arial", 12F, FontStyle.Bold, GraphicsUnit.Pixel))
        using (var fontM15 = new Font("Arial", 12F, FontStyle.Regular, GraphicsUnit.Pixel))
        using (var fontM05 = new Font("Arial", 10F, FontStyle.Regular, GraphicsUnit.Pixel))
        using (var fontM01 = new Font("Arial", 8F, FontStyle.Regular, GraphicsUnit.Pixel))
        using (var stringFormat = new StringFormat())
        {
        }

This way, nested using are not a big deal.

Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
1

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
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 4
    Note that you can write this more compactly. "using(SqlConn conn1 = new SqlConn(), conn2 = new SqlConn()) { stuff }" – Eric Lippert Feb 17 '10 at 22:43
  • 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 Feb 17 '10 at 22:57
  • @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 Feb 17 '10 at 23:21
0

No. Check the generated IL with ILDASM or Reflector.

No Refunds No Returns
  • 8,092
  • 4
  • 32
  • 43
0

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

Stan R.
  • 15,757
  • 4
  • 50
  • 58