Are all disposable objects instantiated within a u

2019-06-16 07:00发布

问题:

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?

回答1:

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



回答2:

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
}


回答3:

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.



回答4:

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.



回答5:

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...
}


回答6:

No. Check the generated IL with ILDASM or Reflector.



回答7:

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