It occurred to me it might be interesting to describe some of the more unconventional uses of IDisposable that can help to make your code more readable, and even apply a kind of AOP-style coding to your code. MSDN describes IDisposable as follows: –
Defines a method to release allocated resources.
In the remarks section it states this: –
The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and stream
However, there is a secondary use for this interface which has absolutely nothing to do with the GC or memory allocation etc.. It comes into being because of the way that the “using” statement works in C#, which behind the scenes, simply calls Dispose() for us once the using statement goes out of scope (in a finally block). We can use this to our advantage in a number of situations where you want have the following behaviour: –
- Turn on something
- Do some code utilising that something
- Turn it off again
- Consider the following (contrived) example – we’re in a dark room and want to write out some text on a keyboard; in order to do that we need to turn on the light whilst we’re typing, and then turn it off when we’re finished: –
A more elegant way might be as follows: –
This is a much more readable version of code; it’s implied from the using statement what the scope of the light is. All we have to do is implement IDisposable on our Light class, and on the constructor and Dispose call the appropriate methods (bear in mind that Dispose gets called automatically once the using statement goes out of scope).
Easy. There are many situations where this pattern could be applied that have nothing to do with managed resources: –
- Temporarily changing the console colour and then having it go back to what it was
- Changing the mouse pointer to an egg-timer whilst doing some time-consuming operation and when it completes resetting it
- Starting a Stopwatch when an operation starts and stopping it when it completes
- Changing some settings on your UI e.g. writeable / read-only etc. when in a particular application state etc.
- In short, anywhere that you want to “temporarily” set the state of something and then reset it again. You can also chain them up: –
Nice. In my second post, I’ll discuss a way of generalising this class of problem and how we can decouple ourselves from IDisposable yet still retain the benefits of the using statement.