The three terms Destructor, Finalizar and Dispose are a bit confusing in dot net. May be you have heard of Finalizer and Dispose but not of Destructor. If your code uses resources that need to released then you can implement IDisposable interface. Then in Dispose method you can clear the resources. But the dispose method is not called automatically rather the user will have to call it explicitly. But if user forgets to call dispose method then how you'll release the resource? Here the Finalizer comes into play. If you implement Finalizer interface then the GC will call the finalize method when the GC will try to reclaim the memory occupied by your object. So Finalize your ensure that you cleaning code will run as GC will call it automatically. But then what about destructor? Actually destructor is just finalizer. In C++ destructor will be called when the object will go out of scope but in C# the desctructor will be called by GC (just like finalizer). So desctructor and finalizer is the same in a sense. In VB.NET there's no destructor but only Finalizer.
Finalizer is costly process and increase the object's generation by 1. When GC runs and try to collect the object and find the object has finalize method, then GC run the finalize method. And after that the GC will not collect the memory rather upgrade the object's generation by 1. So if the object in GEN 0 has finalize method called then the object will be not be reclaimed in this GC call rather the object's generation will be upgraded to GEN 1. So this will keep the object long time in memory. The object memory may be collected next time when the GC will run.
The best design is to include both dispose and finalize in the object which need to clear resources. But if user calls dispose method then we don't need to run the finalize method as the resources are already cleared in dispose method. In that case we can suppress the finalize method by calling GC.SuppressFinalize method. When this method will be called in dispose method the finalizer will not be called thus reclaiming the memory on one single GC run. But if user does not call dispose method then finalizer will be called by GC. For details follow the link: