#428 – A Finalizer Should Always Call the Finalizer of Its Base Class

An implementation of Object.Finalize for a particular class in .NET should always call the Finalize method of its base class.  In the case of C#, you can’t explicitly override Finalize, but you provide a finalizer using the destructor (~) syntax.  When you do this, the compiler will automatically add code to ensure that your destructor calls Finalize in the base class.

In the example below, I write a simple destructor for the Dog class.  We can see in the IL that the Finalize method has been overridden and that it calls System.Object.Finalize in the finally clause.

        ~Dog()
        {
            Trace.WriteLine("This dog is on the way out..");
        }

Advertisements

#427 – Finalizer Gotchas

The idea of the finalizer in .NET is that you can override the Object.Finalize method, called by the garbage collector when it’s releasing memory for an object, and you can do any required cleanup of unmanaged resources.

There are several things to keep in mind if you want to write a finalizer (done in C# using the destructor syntax):

  • You can’t predict when your finalizer is called
  • The finalizer might never get called at all
  • The order that finalizers are called in is unpredictable.  You therefore can’t assume that any other managed object that your object references still exists, or is in a known state.
  • Garbage collection will take longer if you have objects with finalizers

 

#426 – Use a Destructor to Free Unmanaged Resources

When an object is no longer referenced by other objects, its memory may be reclaimed by the garbage collector in the CLR.  If you have any unmanaged resources that you need to clean up explicitly, you can implement a finalizer for your class.

A finalizer is the implementation of the Object.Finalize method for your class, which the garbage collector calls when it’s ready to release memory for an object.  In C#, you implement a finalizer using the destructor syntax–a method defined as a tilde (~), followed by the name of the class.

    public class Dog
    {
        ~Dog()
        {
            Trace.WriteLine("This dog is on the way out..");
        }

When you look at the IL for this class, you’ll see that the compiler has overridden the Finalize method.

You’ll notice that this method is now called when the garbage collector is releasing the object.