2

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 } } } 
2
  • 1
    Yes you need multiple using block so that each object dispose function is invoked when the scope of using block ends. Commented Sep 28, 2013 at 14:43
  • 1
    Note that the need to remember to Dispose() just shifts to the need to remember using() {}. The main plusses of this are readability and exception-safety. Commented Sep 28, 2013 at 15:15

3 Answers 3

7

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(); } 
Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.