If your code makes use of a managed resource, such as a SqlConnection, that implements IDisposable then your code has a responsibilitiy to ensure it is properly disposed of – a responsibility to implement IDisposable itself.
How we should do this is not clearly defined though it becomes obvious quite quickly that Microsoft has a definite pattern that we should be following for “Best Practice”. It took a while, but I finally found a good explanation for this pattern here.
I’ll try to explain it here as best I can, using my own code as an example. I have a class that implements SqlConnection as a private member variable. The code does a lot of database work and I wanted to reuse the same connection object as much as possible. Keeping this variable inside my class however requires my code to implement the IDisposable method – to ensure its properly disposed of.
First up, and most confusingly, we are required to implement a private dispose method that takes a bool as a parameter. This isn’t automatically added if we get visual studio to fill in the template so it has a lot of people confused. Here is a basic implementation of this method from my example.
private void Dispose(bool disposing)
connection = null;
Now this code takes a boolean variable called disposing. Basically, this value determines where the dispose method was called from – there are two possible places. The first, is the implemented Dispose() method that I will show in a moment, and the second is the class finalizer – if one exists. If the method is called from Dispose(), then true should be passed to the it. If its called from the finalizer, then false should be passed.
From what I can see, the difference is that calling Dispose(true) should ensure that all managed objects are disposed of. (Such as my SqlConnection object). If Dispose(false) is called, all that should be skipped, but we should still dispose of any natively allocated resources (resources allocated using AllocHGlobal or the like.) Native resources should be disposed of regardless of the parameter, so should be placed after the main if statement in Dispose().
Now for the example, we have no native resources and thus don’t need a finalizer. All we need now is the Dispose() function.
public void Dispose()
The first statement calls dispose and makes it all happen. The second tells the garbage collector to avoid finalizing this object – I guess to avoid calling Dispose(bool) twice.
Thats pretty much all there is to it. If you can think of anything else pertinent that i’ve missed, comments are welcome.