Having destructor (~Object()) in managed programming language is the most dummest idea.
It perfectly make sense for unmanaged languages like C,C++ to have destructors as they use RAII idiom but for managed like Java,C#, just so absurd.
It has been pointed out by Joshua Bloch, a former project lead in Java Collection Framework, that the idea of finalize() method (which is equivalent to C#'s C++ like destructor) in Java was the biggest mistake ever made. Same as C#, finallize() in Java gives overhead to "new" as it must be added to the finallizer queue during allocation. More over, Garbage Collector must pop and run finallize() in the queue, so twice the overhead during gc.
C# had many enhanced features like "using(IDisposable) {}" which not only allow the IDisposable variable to be confined to the scope of "using" block but also guarantee it's cleanup.
My question is, why did C# follow the same trail of Java which lead to great mistake.
May be if the development of dotnet started after around 2003 ~ 2005, when many Java architects found the fallacy of finallize(), then the mistake would have been prevented.
Many good idea of one language is often transferred to other language like the "IDisposable/using combo " in C# which was transferred to Java 1.7 in its "try(object-to-dispose) {}" statement. But its too bad that language architects fail to discover the bad idea disguised as good idea during it's transfer from one to the other.
My advise is never to use ~Destructor() and stick with IDisposable/using combo if you need to manually cleanup the unmanaged resource like database connections.