The C # language destructor syntax is too overshadowed by what the finalizer does. Perhaps itβs best to demonstrate an example program:
using System; class Program { static void Main(string[] args) { var obj = new Example(); obj = null;
Output:
Finalized finalizer called Basic Finalizer called
There are some noteworthy things about this behavior. The Example class itself does not have a finalizer, but its base class finalizers are invoked anyway. That the Derived class Finalizer is called before the Base class finalizer is not random. Note that the finalizer of the Derived class does not have a call to base.Finalize (), although the MSDN article for Object.Finalize () requires it to be executed, but it is still called.
You can easily recognize this behavior, this is the way the virtual method behaves. The one whose redefinition invokes the underlying method is usually overridden by virtual methods. Otherwise, exactly what is inside the CLR, Finalize () is a simple virtual method like any other. The actual code generated by the C # compiler for the Derived class destructor resembles this:
protected override Derived.Finalize() { try { Console.WriteLine("Derived finalizer called"); } finally { base.Finalize(); } }
Invalid code, but a way to reverse it from MSIL. C # syntactic sugar ensures that you never forget to call the base finalizer and that it cannot be interrupted by interrupting a thread or unloading an AppDomain. The C # compiler does not help and automatically generates a finalizer for the Example class; The CLR does the necessary work of finding the finalizer of the derived class itself, crossing the method tables of the base classes until it finds them. It also helps in the class loader by setting a flag indicating that the example has base classes with a finalizer, so it should be handled specifically by the GC. The base class finalizer calls Object.Finalize (), although it does nothing.
So, the key point is that Finalize () is actually a virtual method. Therefore, this object requires a slot in the method table, so a derived class can override it. Whether it was done otherwise is rather subjective. Of course, it is not easy and not without coercion to each implementation of the language in a special case.
source share