UPDATE: This question was the subject of my blog in May of 2015. Thanks for the great question! See the blog for a long list of falsehoods that people commonly believe about finalization.
When should I manually create a destructor?
Typically one only creates a destructor when your class is holding on to some expensive unmanaged resource that must be cleaned up when the object goes away. It is better to use the disposable pattern to ensure that the resource is cleaned up. A destructor is then essentially an assurance that if the consumer of your object forgets to dispose it, the resource still gets cleaned up eventually. (Maybe.)
If you make a destructor be extremely careful and understand how the garbage collector works. Destructors are really weird:
- They don’t run on your thread; they run on their own thread. Don’t cause deadlocks!
- An unhandled exception thrown from a destructor is bad news. It’s on its own thread; who is going to catch it?
- A destructor may be called on an object after the constructor starts but before the constructor finishes. A properly written destructor will not rely on invariants established in the constructor.
- A destructor can “resurrect” an object, making a dead object alive again. That’s really weird. Don’t do it.
- A destructor might never run; you can’t rely on the object ever being scheduled for finalization. It probably will be, but that’s not a guarantee.
Almost nothing that is normally true is true in a destructor. Be really, really careful. Writing a correct destructor is very difficult.
When have you needed to create a destructor?
When testing the part of the compiler that handles destructors. I’ve never needed to do so in production code. I seldom write objects that manipulate unmanaged resources.