Finalization and implementing IDisposable
are not two separate options; they should always be done together. You should always implement IDisposable
and clean up your resources in Dispose()
, so that users can ensure that unmanaged resources are cleaned up in a timely fashion. And you Dispose()
method should always finish off by calling GC.SuppressFinalize(this) to make sure its finalizer doesn't get called, for reasons that will be explained in a moment.
You should always implement ~MyObject()
when you implement IDisposable
. Its purpose is to give the garbage collector a way to ensure your object is always disposed of in case the people who are using it fail to take care of that themselves. If your finalizer is doing much more than calling this.Dispose()
then you're probably using it incorrectly. Nope. See Ilian Pinzon's comments below, and I've apparently got some documentation to try reading again.
It's really just a safety net. Ideally, the finalizer should actually never be called, because objects are always explicitly disposed instead. When the garbage collector invokes it, it's forced to skip collecting that object. That in turn means that it gets passed along to the second garbage collector generation. Which in turn means that the object will stay in memory much longer, and ultimately be more expensive to clean up.
See here and here for more information on how it should be done.
That said, the best option is to get those disposable objects out of the class context and make them method variables instead whenever possible.
For example, if you've got a class that connects to a database, don't store a master instance of SqlConnection
as a field. Instead, have your public methods create their own connections, and pass them to private methods as needed. This has two advantages: First, it means that you can declare your SqlConnections
in using
blocks and be done with it. Second, getting rid of that piece of 'global' state will help with thread safety, if you ever need it. (There are other advantages specific to `SqlConnection, but those are the general ones.)