This is what I understand about IDisposable and finalizers from "CLR via C#", "Effective C#" and other resources:
- IDisposable is for cleaning up managed and unmanaged resources deterministically.
- Classes that are responsible for unmanaged resources (e.g. file handles) should implement IDisposable and provide a finalizer to guarantee that they are cleaned up even if the client code does not call Dispose() on the instance.
- Classes that are responsible for managed resources only should never implement a finalizer.
- If you have a finalizer then you must implement IDisposable (this allows client code to do the right thing and call Dispose(), while the finalizer prevents leaking resources if they forget).
While I understand the reasoning for and agree with all of the above, there is one scenario where I think it makes sense to break these rules: a singleton class that is responsible for unmanaged resources (such as providing a single point of access to particular files).
I believe it is always wrong to have a Dispose() method on a singleton because the singleton instance should live for the life of the application and if any client code calls Dispose() then you are stuffed. However, you want a finalizer so that when the application is unloaded the finalizer can clean up the unmanaged resources.
So having a singleton class with a finalizer that does not implement IDisposable seems to me to be a reasonable thing to do, yet this type of design is counter to what I understand are best practices.
Is this a reasonable approach? If not, why not and what are the superior alternatives?