First of all - in your example you are using the IDisposable
interface, which has nothing to do with GC at all. In essence, your code compiles to this:
SqlConnection cn = null;
try
{
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
// Set all previous settings to inactive
using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
{
cmd.ExecuteNonQuery();
}
cn.Close();
}
finally
{
if ( cn != null )
cn.Dispose();
}
Since cn.Dispose()
and cn.Close()
are the same in this case - yes, the latter is redundant.
Now, if you wanted to talk about GC, then you'd write like this:
SqlCOnnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
// Set all previous settings to inactive
using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
{
cmd.ExecuteNonQuery();
}
cn = null; // Or just leave scope without doing anything else with cn.
In this case it would take the GC to close the opened connection and return it to the pool. And in this case it would mean that you could not predict when that happened. In practice this code would (with high probability) leak SqlConnections and soon you'd run out of them (you'd get a TimeoutException because there would be no available connections in the pool).
So, yes, your above example is the correct way to go. Whenever you use some object that implements IDisposable
, wrap it in a using
block. And you don't need to bother with the .Close()
, although it doesn't hurt either. I personally don't write it though. Less code, less mess.