Building Finalizable Objects

Finalize() method : The gc will call an object's Finalize() method before removing the object from memory.

Note: It's illegal to override Finalize() on structure types. This makes perfect sense given that structures are value types, which are never allocated on the heap to begin with and, therefore, are not garbage collected. However, if you create a structure what contains unmanaged resources that need to be cleaned up you can implement the IDisposable interface.

Rule: The only compelling reason to override Finalize() is if your C# class is using unmanaged resources via PInvoke or complex COM interoperability tasks (System.Runtime.InteropServices.Marshal type). The reason is that under these scenarios you are manipulating memory that the runtime cannot manage.


Overriding System.Object.Finalize()

class MyResourceWrapper
 {
     // compile-time error!
     protected override void Finalize() { }
 }

Rather, when you want to configure your custom C# class types to override the Finalize() method, you make use of (C# like) destructor syntax to achieve the same effect.

Finalizers are prefixed with a tilde symbol (~). Unlike a constructor, however, a finalizer never takes an access modifier (they are implicitly protected) never takes parameters, and can't be overloaded (only one finalizer per class).

// Override System.Object.Finalize() via Finalizer syntax
class MyResourceWrapper
 {
     // Clean up unmanaged resources here
     // Beep when destroyed (testing purposes only!)
     ~MyResourceWrapper()
     {
         Console.Beep();
     }
 }

static void Main(string[] args)
 {
     CreateObjects(100);
     GC.Collect(0, GCCollectionMode.Forced);
     GC.WaitForPendingFinalizers();
 }
static void CreateObjects(int c)
 {
     MyResourceWrapper[] t = new MyResourceWrapper[c];
     for(int i = 0; i < c; i++)
     {
         t[i] = new MyResourceWrapper();
     }
     t = null;
 }

Detailing the Finalization Process

When you allocate an object onto the managed heap the runtime automatically determines whether your object supports a custom Finalize() method. If so, the object is marked as finalizable, and a pointer to this object is stored on an internal queue named finalization queue. This queue is a table maintained by the gc that points to every object that must be finalized before it is removed from the heap.

When the gc determines it is time to free an object from memory, it examines each entry on the finalization queue and copies the object off the heap to yer another managed structure termed the finalization reachable table (often abbreviated as reachable and pronounced "eff-reacahable").

At this point, a separate thread is spawned to invoke the Finalize() method for each object on the reachable table at the next garbage collection. Given this, it will take, at the least, 2 gcs to truly finalization object.

Building Disposable Objects

As you have seen, finalizers can be used to release unmanaged resources when the gc kicks in. However, given that many unmanaged objects are "precious items" (such as raw db or file handles), it could be valuable to release them as soon as possible instead of relying on a gc to occur. As an alternative to overridding Finalize(), your class could implement the IDisposable interface, which defines a single method named Dispose().

public interface IDisposable
 {
     void Dispose();
 }

When you do implement the IDisposable interface, the assumption is that when the "object user" is finished using the object, the object user manually calls Dispose() before allowing the object reference to drop out of scope.

class MyResourceWrapper : IDisposable
 {
     public void Dispose()
     {
         // Clean up managed resources.
     }
 }

MyResourceWrapper m = new MyResourceWrapper();
m.Dispose();

Reusing the C# using Keyword

try
 {
     m = new MyResourceWrapper();
 }finally
 {
     m.Dispose();
 }
The upside block equals to the :
 
using (MyResourceWrapper m = new MyResourceWrapper())
 {
     // 
 }

It's also possible to declare multiple objects of the same type within a using scope.

using (MyResourceWrapper m = new MyResourceWrapper(),m2 = new MyResourceWrapper())
 {
     //
 }

Using Declarations

New in C# 8.0 is the addition of using declarations. A using declaration is a variable declaration proceed by the using keyword.

private static void UsingDeclaration()
 {
     using var rw = new MyResourceWrapper();
 }