Garbage collector takes care of Automatic memory management. But sometimes we need to use the Dispose and Finalize methods for object destruction. While using Dispose and Finalize methods extreme care needs to be taken.
Cautions for using Finalize ()
- Implement Finalize on an object that requires finalization. Performance costs are associated with it.
- Don’t make the Finalize method more visible. It should be protected. Never use public.
- In-case you require to use Finalize method, first consider implementing the IDisposable. It has got the advantage of allowing the users to avoid the cost of invoking the Finalize method.
- An object’s Finalize method should free all the external resources that the object was referencing to. The Finalize method should not reference to any other objects.
Cautions for using Dispose ()
- Implementing the Dispose design pattern on a type that encapsulates the resources that explicitly need to be freed. Users can free the external resources by calling the Public Dispose method.
§ Implement the dispose design pattern on a base type that commonly has derived types that hold on to resources, even if the base type does not. If the base type has a close method, often this indicates the need to implement Dispose. In such cases, do not implement a Finalize method on the base type. Finalize should be implemented in any derived types that introduce resources that require cleanup.
- Free any Disposable resources on a type owns in its Dispose method.
- After Dispose had been invoked on a instance, Prevent the Finalize method from running which calls the GC.SuppressFinalize method.
- Call the Base class’s Disposable method if it implements IDisposable which will give some performance benefits.
- Don’t ever assume that Dispose will be called. Unmanaged resources owned by a type should also be released in a Finalize method in the event that Dispose is not called.
§ Throw an ObjectDisposedException from instance methods on this type (other than Dispose) when resources are already disposed. This rule does not apply to the Dispose method because it should be callable multiple times without throwing an exception.
§ Propagate the calls to Dispose through the hierarchy of base types. The Dispose method should free all resources held by this object and any object owned by this object. For example, you can create an object like a TextReader that holds onto a Stream and an Encoding, both of which are created by the TextReader without the user's knowledge. Furthermore, both the Stream and the Encoding can acquire external resources. When you call the Dispose method on the TextReader, it should in turn call Dispose on the Stream and the Encoding, causing them to release their external resources.
§ We should consider not allowing an object to be usable after its Dispose method has been called. Recreating an object that has already been disposed is a difficult pattern to implement.
Allow a Dispose method to be called more than once without throwing an exception. The method should do nothing after the first call.