Tom S
Tom S

Reputation: 135

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". 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!

Let's say though that I start with a new SqlConnection which I handle within a using statement. Within that block of code I create some additional IDisposables, for example a SqlDataAdapter. Does that adapter need it's own using statement?

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)? Or do I need multiple using statements, maybe something like:

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

Upvotes: 2

Views: 182

Answers (3)

Henk Holterman
Henk Holterman

Reputation: 273264

Does that adapter need it's own using statement?

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. Even for MemoryStream where Dispose() does nothing. 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. And then we fudge on the indentation a little.

Upvotes: 3

Marc Gravell
Marc Gravell

Reputation: 1062865

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":

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

Upvotes: 7

Sebastian &#208;ymel
Sebastian &#208;ymel

Reputation: 717

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

Upvotes: 0

Related Questions