Normally, the CLR keeps tabs on objects with a finalizer when they are created (making them more expensive to create). SuppressFinalize tells the GC that the object was cleaned up properly and doesn't need to go onto the finalizer queue. It looks like a C++ destructor, but doesn't act anything like one.

The SuppressFinalize optimization is not trivial, as your objects can live a long time waiting on the finalizer queue. Don't be tempted to call SuppressFinalize on other objects mind you. That's a serious defect waiting to happen.

Design guidelines inform us that a finalizer isn't necessary if your object implements IDisposable, but if you have a finalizer you should implement IDisposable to allow deterministic cleanup of your class.

Most of the time you should be able to get away with IDisposable to clean up resources. You should only need a finalizer when your object holds onto unmanaged resources and you need to guarantee those resources are cleaned up.

Note: Sometimes coders will add a finalizer to debug builds of their own IDisposable classes in order to test that code has disposed their IDisposable object properly.