If a class overrides a method called Finalize and an instance of that class is found to have been abandoned without GC.SuppressFinalize() having been called upon that instance, the GC will store a reference to the object in a list of things whose Finalize should be run ASAP (temporarily resurrecting it) and mark the object so that the next time it's abandoned it will simply disappear. If any objects have been placed on the list for immediate finalization, the GC will then launch a thread to run their Finalize methods.
For whatever reason, the creators of C# decided to confuse things a little bit by forbidding programmers from overriding Finalize directly and instead requiring that programmers wishing to override Finalize use a construct they call a "destructor", with syntax reminiscent of a C++ destructor, but totally different semantics. Although C# adds a little bit of wrapper code, one can generally think of ~className {whatever} as being roughly equivalent to overriding Finalize.
Microsoft recommends that if one overrides Finalize (or implements a C# destructor), that override/destructor should simply call a method with signature void Dispose(bool), passing False for the parameter value. It based upon that advice that people get the idea that the GC calls Dispose. Note that the GC itself doesn't call Dispose; note further that most objects shouldn't implement C# destructors nor override Finalize in any other way. Unless one understands all the corner cases involved with Finalize, it's generally better to ensure that IDisposable.Dispose gets called before objects are abandoned.