Различные способы использования использования в С#

Я смотрю на использование в С#, и я хочу знать, эквивалентен ли следующий код:

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

К этому коду;

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

Ответы

Ответ 1

С# Spec говорит,

Когда сбор ресурсов принимает форма объявления локальной переменной, можно получить несколько ресурсов данного типа. Использование утверждение формы

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

точно эквивалентна последовательности вложенных операторов:

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

Ответ 2

Вы можете, конечно, вставить некоторый код между первым и вторым использованием, который использует connection1 перед созданием соединения 2.

Но вы этого не сделаете, так как нет никакой разницы. Оба они производят один и тот же 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  

Ответ 3

Да, эти две части кода эквивалентны.

Изменить

Просто проверил это с помощью Reflector. Точный же IL испускается для двух версий, и Reflector декомпилирует следующий С#:

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

То есть для обеих версий Dispose будет вызываться в обоих экземплярах, даже если один из них генерирует исключение в конструкторе.

Ответ 4

Да, согласно раздел 8.13 Спецификации языка С#:

Когда сбор ресурсов принимает форма объявления локальной переменной, можно получить несколько ресурсов данного типа. Использование утверждение формы

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

Оператор

точно эквивалентной последовательности вложенные операторы:

using (ResourceType r1 = e1)
using (ResourceType r2 = e2)
...
using (ResourceType rN = eN)
    операторкод >

Ответ 5

Да, они точно такие же. Вы можете использовать Reflector, чтобы это доказать.

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

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

Ответ 6

В дополнение к отличному упоминанию С# 8.13 других ответов, случай с одним предложением должен быть переписан, когда один из ресурсов должен изменить тип.

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

Когда r2 необходимо изменить на новый тип, это должно стать

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

Итак, лучше использовать последний. (Лично я считаю, что это лучше читается)