在C#中使用Using的不同方式

时间:2010-10-15 16:02:47

标签: c#

我一直在使用C#,我想知道以下代码是否相同;

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

到此代码;

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

6 个答案:

答案 0 :(得分:27)

C# Spec说,

  

当资源获取需要时   本地变量声明的形式,   有可能获得多个   给定类型的资源。一个使用   表格陈述

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

恰好等同于一个序列   嵌套使用语句:

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

答案 1 :(得分:7)

您当然可以在第一个和第二个之间插入一些代码,在创建connection2之前使用connection1。

但你不是,所以没有区别。它们都产生相同的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  

答案 2 :(得分:5)

是的,这两段代码是等价的。

修改

刚刚用Reflector测试了这个。两个版本都发出了完全相同的IL,Reflector反编译为以下C#:

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

也就是说,对于这两个版本,即使在构造函数中抛出异常,也会在两个实例上调用Dispose。

答案 3 :(得分:5)

是的,根据section 8.13 of the C# Language Specification

  

当资源获取需要时   本地变量声明的形式,   有可能获得多个   给定类型的资源。一个使用   表格陈述

     

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

     声明是   恰好等同于一系列   嵌套使用语句:

     

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

答案 4 :(得分:3)

是的,它们完全一样。您可以使用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())
        {
        }
    }

答案 5 :(得分:1)

除了很好地提及其他答案的C#8.13之外,当其中一个资源必须改变类型时,必须重写单子句案例。

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

r2需要更改为新类型时,必须变为

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

所以你最好使用后者。 (就个人而言,我发现它的读数也更好)