15

I have been looking at using in C# and I want to know if the following code is equivalent;

using (SqlConnection connection1 = new SqlConnection(), connection2 = new SqlConnection())
{
}

To this code;

using (SqlConnection connection1 = new SqlConnection())
using (SqlConnection connection2 = new SqlConnection())
{
}
3
  • I'd say they are the same, but I could be wrong... you could test it out though. Commented Oct 15, 2010 at 16:04
  • The two are equivalent. Please see the following SO question: stackoverflow.com/questions/1329739/… Commented Oct 15, 2010 at 16:05
  • 9
    Personally, I think the second one is easier to read. Commented Oct 15, 2010 at 16:07

6 Answers 6

27

The C# Spec says,

When a resource-acquisition takes the form of a local-variable-declaration, it is possible to acquire multiple resources of a given type. A using statement of the form

    using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement

is precisely equivalent to a sequence of nested using statements:

    using (ResourceType r1 = e1)
       using (ResourceType r2 = e2)
          ...
             using (ResourceType rN = eN)
                statement
Sign up to request clarification or add additional context in comments.

Comments

7

You can of course insert some code between the first and second using, that uses connection1 before connection2 is created.

But you aren't, so as it is there is no difference. They both produce the same IL:

IL_0000:  newobj      System.Data.SqlClient.SqlConnection..ctor
IL_0005:  stloc.0     
IL_0006:  newobj      System.Data.SqlClient.SqlConnection..ctor
IL_000B:  stloc.1     
IL_000C:  leave.s     IL_0018
IL_000E:  ldloc.1     
IL_000F:  brfalse.s   IL_0017
IL_0011:  ldloc.1     
IL_0012:  callvirt    System.IDisposable.Dispose
IL_0017:  endfinally  
IL_0018:  leave.s     IL_0024
IL_001A:  ldloc.0     
IL_001B:  brfalse.s   IL_0023
IL_001D:  ldloc.0     
IL_001E:  callvirt    System.IDisposable.Dispose
IL_0023:  endfinally  

Comments

5

Yes, according to section 8.13 of the C# Language Specification:

When a resource-acquisition takes the form of a local-variable-declaration, it is possible to acquire multiple resources of a given type. A using statement of the form

using (ResourceType r1 = e1, r2 = e2, ..., rN = eN)

statement is precisely equivalent to a sequence of nested using statements:

using (ResourceType r1 = e1)
using (ResourceType r2 = e2)
...
using (ResourceType rN = eN)
    statement

Comments

5

Yes, those two pieces of code are equivalent.

Edit

Just tested this with Reflector. Exact same IL is emitted for the two versions, and Reflector decompiles to the following C#:

using (new SqlConnection())
{
    using (new SqlConnection())
    {
    }
}

That is, for both versions, Dispose will be called on both instances, even if one throws an exception in the constructor.

Comments

3

Yes, they are exactly the same. You can use Reflector to prove this.

    public void Method1()
    {
        using (SqlConnection connection1 = new SqlConnection())
        using (SqlConnection connection2 = new SqlConnection())
        {
        }
    }

    public void Method2()
    {
        using (SqlConnection connection1 = new SqlConnection(), connection2 = new SqlConnection())
        {
        }
    }

Comments

1

In addition to the excellent mentioning of C# 8.13 of other answers, the single-clause case is going to have to be rewritten when one of the resources has to change type.

using( S r1 = new S(), r2 = new S() )
{
  ...
}

When r2 needs to be changed into a new type, this has to become

using( S r1 = new S() )
using( T r2 = new T() )
{
  ...
}

So you're better of using the latter. (Personally, I find it reads better, too)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.