Dispose() method permanently removes connection object from memory and the resource no longer exists for any further processing.
Design Pattern : If your classes use unmanaged resources, you need to implement both Dispose & Finalize. Dispose() is
called by user code, that is, the code that is using your class.
Finalize/Destructor cannot be called by User code, it's called by Garbage
Finalize : Is a destructor, called by Garbage Collector when the object goes
out of scope. Implement it when you have unmanaged resources in your code, and
want to make sure that these resources are freed when the Garbage collection
Dispose : Same purpose as finalize, to free unmanaged resources. However,
implement this when you are writing a custom class, that will be used by other
users. Overriding Dispose() provides a way for the user code to free the
unmanaged objects in your custom class
The Garbage Collector calls this method at some point after there are no longer valid references to that object in memory.
The framework does not guarantee that when this will happen, you can force for Garbage Collection but it will hurt performance of your program. Finalize() belongs to the Object class and it will be called by the runtime.
There are some resources like windows handles, database connections , network connections, files, etc. which cannot be collected by the Garbage Collector. If you want to explicitly release some specific objects then this is the best to implement IDisposable and override the Dispose() method of IDisposable interface.