We implement the Finalize method to release the unmanaged resources. Before proceeding, first let’s see what managed and unmanaged resources are.
Managed resources are the ones that we write in .Net languages. But when we write code in any non-.Net language like VB 6 or any windows API, we call it unmanaged. And there is a very high chance that we use a Windows API or a COM component in our application. So, since managed resources are not managed by the CLR, we need to handle them on our own. So, once we are done with unmanaged resources, we need to clean them up. The cleanup and releasing of unmanaged resources is done in Finalize(). If your class is not using any unmanaged resources then you can forget about Finalize(). But the problem is, we can’t directly call Finalize(), we do not have control of it. Then who is going to call this? Basically the GC calls it.
And one more thing to remember is, there is no Finalize keyword that we write and implement it. We can define Finalize by defining the destructor. The destructor cleans up unmanaged resources. When you put the "~" sign in front of the class name, it will be treated as the destructor. So, when the code is compiled, the destructor will convert that into Finalize and further the Garbage Collector will add it to the Finalize queue.
Let’s use this sample code:
class A
{
public A()
{ Console.WriteLine("I am in A"); }
~A()
{ Console.WriteLine("Destructor of A"); }
}
class B : A
{
public B()
{ Console.WriteLine("I am in B"); }
~B()
{ Console.WriteLine("Destructor of B"); }
}
class C : B
{
public C()
{ Console.WriteLine("I am in C"); }
~C()
{ Console.WriteLine("Destructor of C"); }
}
Now using the Reflector we will see if the destructor is really converted to Finalize:
And WOW, it really is. Here we can see that there is nothing like a destructor. Basically the destructor is overriding the Finalize method.