在另一个IDisposable“using”语句中处理IDisposable

时间:2013-09-28 14:38:11

标签: c#

我对C#还是比较陌生的,并且在过去的几天内只接触过“IDisposables”。我可以掌握using块的概念来处理必须处理的对象,而无需手动记住调用.Dispose()方法 - 方便!

让我们说,我从一个新的SqlConnection开始,我在using语句中处理。在该代码块中,我创建了一些额外的IDisposable,例如SqlDataAdapter。该适配器是否需要它自己的using语句?

例如,如果我有代码......

using (SqlConnection myConnection = new SqlConnection())
{
    SqlCommand myCommand = new SqlCommand();
    SqlDataAdapter myAdapter = new SqlDataAdapter();
    // Do things
}

... myCommandmyAdapter会在处置myConnection时被处置掉(因为它们在该代码块的范围内)?或者我需要多个using语句,可能类似于:

using (SqlConnection myConnection = new SqlConnection())
{
    using (SqlCommand myCommand = new SqlCommand())
    {
        using (SqlDataAdapter myAdapter = new SqlDataAdapter())
        {
            // Do things
        }
    }
}

3 个答案:

答案 0 :(得分:7)

严格来说,处置所有这些都是最好的。但是,您可以通过直接嵌套来避免缩进:

using (var myConnection = new SqlConnection())
using (var myCommand = new SqlCommand())
using (var myAdapter = new SqlDataAdapter())
{
    // Do things
}

或者,特别是在ADO.NET的情况下(让我们公平,有很多一次性类型),您可能会发现使用其中一个隐藏了大量管道的库更容易 - 例如,“dapper”:

using(var conn = new SqlConnection(...))
{
    return conn.Query<Customer>(
        "select * from Customers where Region=@region",
        new { region }).ToList();
}

答案 1 :(得分:3)

  

那个适配器是否需要它自己的using语句?

在这种情况下,没有。但这取决于对Connection和Adapter对象的详细了解,以及最佳实践:每using()使用一个IDisposable。即使对于Dispose()什么也不做的MemoryStream。它们很便宜。

您的代码是正确的,但我们通常会节省{}

using (SqlConnection myConnection = new SqlConnection())
using (SqlCommand myCommand = new SqlCommand())    
using (SqlDataAdapter myAdapter = new SqlDataAdapter())
{
    // Do things
}

我们在此使用规则,当using()控制1个语句(下一个using())时,您不需要大括号。然后我们稍微捏造压痕。

答案 2 :(得分:0)

使用只是

的语法糖
            var connection = new Connection();
        try
        {
            connection.DoSomething();
        }
        finally
        {
            // Check for a null resource.
            if (connection != null)
            {
                ((IDisposable)connection).Dispose();
            }
        }

所以是的,你需要嵌套的using语句来确保处理所有这些