CHAPTER 13 UNDERSTANDING OBJECT LIFETIME
on the managed heap and has access to all other heap-allocated objects. The calling logic, shown here, is
straightforward:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Dispose *****\n");
// Create a disposable object and call Dispose()
// to free any internal resources.
MyResourceWrapper rw = new MyResourceWrapper();
rw.Dispose();
Console.ReadLine();
}
}
Of course, before you attempt to call Dispose() on an object, you will want to ensure the type
supports the IDisposable interface. While you will typically know which base class library types
implement IDisposable by consulting the .NET Framework 4.5 SDK documentation, a programmatic
check can be accomplished using the is or as keywords discussed in Chapter 6.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Dispose *****\n");
MyResourceWrapper rw = new MyResourceWrapper();
if (rw is IDisposable)
rw.Dispose();
Console.ReadLine();
}
}
This example exposes yet another rule regarding memory management:
Rule It is a good idea to call Dispose() on any object you directly create if the object supports
IDisposable. The assumption you should make is that if the class designer chose to support the Dispose()
method, the type has some cleanup to perform. If you forget, memory will eventually be cleaned up (so don’t
panic), but it could take longer than necessary.
There is one caveat to the previous rule. A number of types in the base class libraries that do
implement the IDisposable interface provide a (somewhat confusing) alias to the Dispose() method, in
an attempt to make the disposal-centric method sound more natural for the defining type. By way of an
example, while the System.IO.FileStream class implements IDisposable (and therefore supports a
Dispose() method), it also defines the following Close() method that is used for the same purpose:
490