- In C#, finalizers are represented by the ~ClassName [destructor syntax], and the Object.finalize can neither be overridden or called directly. It cannot be called directly because it is protected. The destructors in C# also take care of calling the dtor of the base class.
- Finalizer is called on an object only once, just before the .NET runtime attempts to garbage collect the object.
- Finalizers can be called anytime on a managed object that is not being referenced, and on any thread by the .NET runtime.
- The order in which the finalizers are called is also not fixed. Even when two objects are related to each other in some way, there is no hierarchial order in which the finalizers for the objects will be called.
- During an application shutdown, finalizers will be called even on objects that are still accessible.
The most interesting part of the finalizer is not when it is called but when all is it NOT called. This is where we need to watch and rely on the Dipose method [IDispoable - Dispose pattern].
- When a finalizer of a object blocks indefinitely [deadlock, infinite loop etc].
- When the process terminates improperly without giving the .NET runtime a chance run the finalizers.
- When a managed object is exempt from finalization by calls like GC.SupressFinalize or KeepAlive.