I am working on a class that deals with a lot of Sql objects - Connection, Command, DataAdapter, CommandBuilder, etc. There are multiple instances where we have code like this:
if( command != null )
{
command.Dispose();
}
if( dataAdapter != null )
{
dataAdapter.Dispose();
}
etc
I know this is fairly insufficient in terms of duplication, but it has started smelling. The reason why I think it smells is because in some instances the object is also set to null.
if( command != null )
{
command.Dispose();
command = null;
}
I would love to get rid of the duplication if possible. I have come up with this generic method to dispose of an object and set it to null.
private void DisposeObject<TDisposable>( ref TDisposable disposableObject )
where TDisposable : class, IDisposable
{
if( disposableObject != null )
{
disposableObject.Dispose();
disposableObject = null;
}
}
My questions are...
null
?EDIT:
I am aware of the using
statement, however I cannot always use it because I have some member variables that need to persist longer than one call. For example the connection and transaction objects.
Thanks!
If you don't use using , then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().
IDisposable is an interface that contains only a single method i.e. Dispose(), for releasing unmanaged resources. IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources.
Dispose improves performance and optimizes memory by releasing unmanageable objects and scarce resources, like Graphics Device Interface (GDI) handles used in applications with restricted Windows space. The Dispose method, provided by the IDisposable interface, implements Dispose calls.
IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.
You should consider if you can use the using
statement.
using (SqlCommand command = ...)
{
// ...
}
This ensures that Dispose
is called on the command object when control leaves the scope of the using. This has a number of advantages over writing the clean up code yourself as you have done:
Is it necessary to set the object to null?
It is not usually necessary to set variables to null when you have finished using them. The important thing is that you call Dispose when you have finished using the resource. If you use the above pattern, it is not only unnecessary to set the variable to null - it will give a compile error:
Cannot assign to 'c' because it is a 'using variable'
One thing to note is that using
only works if an object is acquired and disposed in the same method call. You cannot use this pattern is if your resources need to stay alive for the duration of more than one method call. In this case you might want to make your class implement IDisposable
and make sure the resources are cleaned up when your Dispose method is called. I this case you will need code like you have written. Setting variables to null
is not wrong in this case but it is not important because the garbage collector will clean up the memory correctly anyway. The important thing is to make sure all the resources you own are disposed when your dispose method is called, and you are doing that.
A couple of implementation details:
ObjectDisposedException
if your object has already been disposed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With