My wife speaks of two kinds of trash: “clean” trash and “dirty” trash. This is not a distinction I consciously would have made without being married to her, but I recognize how useful the categories are. “Clean” trash (non-recyclable plastic and the like) can wait till morning for me to haul it outside and the city to pick it up, whereas “dirty” trash (cantaloupe rinds, a chicken carcass, etc) will stink up the house if left inside even for an hour.
Programmers writing code for the .NET Framework deal with these categories of refuse, too. Our clean trash is pure managed code. The garbage man takes care of this for us, and we rarely have to think about it.
Our dirty trash is unmanaged resources, such as handles to Win32 API objects. We want to get that stuff out of the house as soon as we’re done with it, rather than wait for the garbage man to show up. The .NET pattern for this is that such objects must implement the IDisposable interface. C♯ provides syntactic sugar for consumers to hygienically and conveniently handle IDisposable objects: the using statement.
Sometimes while using somebody else’s API you run across a particularly smelly kind of trash:
An example of this software antipattern is the OpenNETCF.Phone.Sim.Sim class. Its documentation states:
It is not recommended that you have more than one SIM object open in your application at one time.
This object helpfully proves a Close method, but it does not implement IDisposable. If it did, we could tidy up by writing:
But instead we’re reduced to this:
Where’s the sink? I need to wash my hands!
I’ve written a class called Disposer<T> that makes cleaning up dirty trash a less distasteful experience. It makes the using block useful for such objects as OpenNETCF’s Sim:
See? Your hands didn’t even get dirty.
Under the covers Disposer<T> uses reflection to get at the Close() method of Sim. There is certainly a performance penalty for using reflection. If you’re calling the same disposal method many times, you can hang onto it and pass it to Disposer<T>:
I wrote this code in a test-driven fashion, so hopefully I’ve managed to keep the bugs away.
Stay healthy! 