2

I frequently use the following code (or alike) to dispose of objects:

SqlCommand vCmd = null;

try 
{
    // CODE
}
catch(Exception ex) { /* EXCEPTION HANDLE */ }
finally 
{
    if (vCmd != null) 
    {
        vCmd.Dispose();
        vCmd = null;
    }
}

Is this the best way to release objects and dispose of objects?

I'm using the VS analytics and give me a warning about redundancies. But I always do it this way...

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
MiBol
  • 1,985
  • 10
  • 37
  • 64

2 Answers2

4

The best way in terms of readability is using the using statement:

using(SqlCommand vCmd = new SqlCommand("...", connection)
{
    try 
    {
        // CODE
    }
    catch(Exception ex) 
    { 
        // EXCEPTION HANDLE
    }
}

It disposes objects even in case of error, so similar to a finally. You should use it always when an object implements IDisposable which indicates that it uses unmanaged resources.

Further reading:

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Key points: 1) There is no need to set objects to "null". 2) Some resources need to be "Closed()". SqlConnection and SqlReader are two examples. You can use "Close()" (my preference), "Dispose()" "Dispose will automatically call Close()) or "using". Most objects do *NOT* implement IDispose and do *NOT* need to be explicitly closed. They do *NOT* need to be set to "Nothing" (like in VB6 days). SqlStatement is one such object - just stop using it, and the GC will do the rest. – FoggyDay Jun 26 '14 at 22:07
  • @FoggyDay: yes, but i've mentioned it. Either directly or via link. So i don't understand the downvote. – Tim Schmelter Jun 26 '14 at 22:09
  • Also, what is `SqlStatement`? Do you mean `SqlCommand`? Then i don't agree, actually it's best practise to use `using` on _all_ objects that implement `IDisposable`. Even if it does not use unmanaged resources today, the fact that ut implements `IDisposable` could indicate that it will use them tomorrow. It doesn't hurt anyway. So yes, dispose also `SqlCommand`. – Tim Schmelter Jun 26 '14 at 22:19
2

Here is an example from MSDN:

private static void ReadOrderData(string connectionString)
{
    string queryString = 
        "SELECT OrderID, CustomerID FROM dbo.Orders;";
    using (SqlConnection connection = new SqlConnection(
               connectionString))
    {
        SqlCommand command = new SqlCommand(
            queryString, connection);
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        try
        {
            while (reader.Read())
            {
                Console.WriteLine(String.Format("{0}, {1}",
                    reader[0], reader[1]));
            }
        }
        finally
        {
            // Always call Close when done reading.
            reader.Close();
        }
    }
}

Note the use of "using" for the connection.

Back in the Olden Days of COM/ActiveX, you needed to set your objects to "Nothing".

In managed code, this is no longer necessary.

You should neither call "Dispose()", nor set your sqlCommand to "null".

Just stop using it - and trust the .Net garbage collector to do the rest.

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
  • I would claim that you are *not* just "trusting the .net garbage collector to do the rest" in that example - you're disposing it by using "using". "using" is just syntactic sugar for "finally { obj.Dispose(); }", after all. – neminem Jun 26 '14 at 21:56
  • 2
    @neminem - Well, more accurately it's syntactic sugar for `finally { ((IDisposible)obj).Dispose(); }` – Mike Christensen Jun 26 '14 at 21:59
  • Mike is correct. Furthermore, you don't need *either* for "SqlCommand". The GC will take care of SqlCommand. You must, however, "Close()" both the SqlConnection and the SqlReader. The main point is that a .Net "Dispose" != a COM/ActiveX "obj = Nothing". – FoggyDay Jun 26 '14 at 22:03