Reputation: 135
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
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
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
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