Search⌘ K
AI Features

Finalizers

Explore how C# finalizers function to clean up unmanaged resources before garbage collection reclaims memory. Understand the restrictions on finalizers, see how the garbage collector processes objects with finalizers, and learn why SafeHandle is preferred for managing unmanaged resources in modern applications.

Most objects used in C# programs are managed by the CLR and are easily cleaned up by the garbage collector. However, there are also objects that involve unmanaged resources, such as file handles, database connections, and network connections. These unmanaged objects access operating system APIs. The garbage collector can handle managed objects, but it does not know how to dispose of unmanaged resources. In these cases, we must implement the cleanup logic ourselves.

Releasing unmanaged resources typically requires implementing one of two mechanisms: creating a finalizer or implementing the IDisposable interface.

Finalizers

While constructors initialize class instances, finalizers (historically called destructors) contain cleanup logic that executes before the garbage collector reclaims an object.

Finalizers have strict rules:

  • They can only be defined in classes.

  • They cannot have access modifiers or parameters.

  • They cannot be inherited or overridden.

Note: Each class can only have one finalizer.

A finalizer uses the class name preceded by a tilde sign (~). Let us look at an example of a class with a finalizer:

class Car
{
// Constructor
public Car()
{
}
// Finalizer
~Car()
{
// Instructions to release unmanaged resources
}
}
Defining a finalizer using the tilde syntax
...