Some objects, in order to behave as specified, need outside entities to do things on their behalf. In some cases, outside entities will be able to do everything that's necessary before a method returns. In other cases, however, a method will need to return after having asked an outside entity keep doing something until further notice (but without having given it such notice). The object thus acquires a responsibility to let the outside entity know when its services are no longer required.
The purpose of IDisposable
is to provide a standardized way by which an object can be told "Your services will no longer be required, so if you've asked any outside entities to start doing something on your behalf so you could in turn use it to satisfy your customers, you should tell them to stop doing so." It generally does not free up any memory (except in cases where an outside entity has reserved some memory to help it satisfy the object's needs), and in many cases need not actually do anything (if no outside entities are doing anything on behalf of some object, nobody will need to be told to stop acting on its behalf).
Finalizers exist primarily to deal with the possibility that objects which implement IDisposable
might get abandoned without their dispose method having been called. It effectively tells an object "It looks as though you've been abandoned, so you should probably clean up". Although Finalize can serve as a "safety net", it should not be considered reliable; generally, if an object which has a finalizer is wrongfully abandoned, the finalizer will get run "sometime", but there's generally no guarantee of timeliness. Thus, when an object which has asked an entity to do something on its behalf is no longer needed, it should be told immediately (via Dispose
) rather than abandoned. In a properly-written program, few finalizers should ever run.