简体   繁体   English

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

[英]Handling IDisposables within another IDisposable “using” statement

I'm still relatively new to C# and have only within the past several days been exposed to "IDisposables". 我对C#还是比较新的,并且在过去的几天内只接触过“IDisposables”。 I can grasp the concept of the using block to take care of objects which must be disposed of without needing to manually remember to call the .Dispose() method - convenient! 我可以掌握using块的概念来处理必须处理的对象,而无需手动记住调用.Dispose()方法 - 方便!

Let's say though that I start with a new SqlConnection which I handle within a using statement. 假设我从一个新的SqlConnection开始,我在一个using语句中处理它。 Within that block of code I create some additional IDisposables, for example a SqlDataAdapter . 在该代码块中,我创建了一些额外的IDisposable,例如SqlDataAdapter Does that adapter need it's own using statement? 该适配器是否需要它自己的using语句?

For example, if I have code... 例如,如果我有代码......

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

... will myCommand and myAdapter be disposed of when myConnection is disposed (since they are within the scope of that code block)? ...当我的myConnection被处理时, myCommandmyAdapter会被处理掉(因为它们在那个代码块的范围内)? Or do I need multiple using statements, maybe something like: 或者我需要多个using语句,可能是这样的:

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

Strictly speaking, it would indeed be best to dispose all of them. 严格来说,处理所有这些问题确实是最好的。 However, you can avoid the indenting by nesting them directly: 但是,您可以通过直接嵌套来避免缩进:

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

Alternatively, specifically in the case of ADO.NET (which does, let's be fair, have a lot of disposable types), you might find it easier to use one of the libraries that hides away a lot of the plumbing - for example, with "dapper": 或者,特别是在ADO.NET的情况下(让我们公平地说,有很多一次性类型),您可能会发现使用其中一个隐藏了大量管道的库更容易 - 例如, “短小精悍”:

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

Does that adapter need it's own using statement? 该适配器是否需要它自己的using语句?

In this case, no. 在这种情况下,没有。 But that depends on detailed knowledge of the Connection and Adapter objects so as a best practice : use one using() per IDisposable . 但这取决于Connection和Adapter对象的详细知识,因此最佳做法是 :每个IDisposable使用一个using() Even for MemoryStream where Dispose() does nothing. 即使对于Dispose()什么也不做的MemoryStream。 They are inexpensive. 它们很便宜。

Your code is correct but we usually economize on the {} : 您的代码是正确的,但我们通常会节省{}

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

We use the rule here that when a using() controls 1 statement (the next using() ), you don't need braces. 我们在这里使用规则,当using()控制1语句(下一个using() )时,你不需要大括号。 And then we fudge on the indentation a little. 然后我们稍微捏造压痕。

Using is just syntatic sugar for 使用只是合成糖

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

So yes, you need nested using statements to be sure to dispose all of these 所以是的,你需要嵌套的using语句来确保处理所有这些

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM