Experienced C++ developers make extensive use of destructors, sometimes not only to clean up
resources but also to provide debugging information or perform other tasks. C# destructors are used far
less than their C++ equivalents. The problem with C# destructors as compared to their C++ counterparts
is that they are nondeterministic. When a C++ object is destroyed, its destructor runs immediately.
However, because of the way the garbage collector works when using C#, there is no way to know when
an object ’ s destructor will actually execute. Hence, you cannot place any code in the destructor that relies
on being run at a certain time, and you should not rely on the destructor being called for different class
instances in any particular order. When your object is holding scarce and critical resources that need to
be freed as soon as possible, you do not want to wait for garbage collection.
Another problem with C# destructors is that the implementation of a destructor delays the final removal
of an object from memory. Objects that do not have a destructor are removed from memory in one
pass of the garbage collector, but objects that have destructors require two passes to be destroyed:
The first pass calls the destructor without removing the object, and the second pass actually deletes the
object. In addition, the runtime uses a single thread to execute the Finalize() methods of all objects.
If you use destructors frequently, and use them to execute lengthy cleanup tasks, the impact on
performance can be noticeable.
page 335 of Professional c# 2008 by Wrox