This is a destructor. The syntax is inherited from C ++. But the semantics are quite different.
In practice, destructors do not exist in language. To understand I will explain two other concepts.
Dispose
This is a method available in all types that implement the IDisposable
interface and allows resources to be freed when the object is no longer needed. The call of Dispose()
can be done manually at any time or automatically using statement using
. The release of resources are free memory. Only the garbage collector allows you to free the memory. If a type does not need external resources, it is unnecessary.
Finalize
This is the method that actually processes everything that is needed the moment before the memory release. We can say that it is responsible for the release, although the one who does this is the garbage collector . A finalize()
is always available, because it is part of type Object
and in most cases the default implementation of Object
is sufficient.
Destroyer
You can not override a Finalize()
method on its type. The compiler does not allow you to use your own implementation. But it allows the destructor to be created. And it can process what you want in the destructor and call the Finalize()
. The default implementation of Finalize
must be available in all types.
Then the code
class Car {
~Car() { // destrutor
// código de limpeza...
}
}
is the same as
protected override void Finalize() {
try {
// código de limpeza...
} finally {
base.Finalize();
}
}
but the second form can only be generated by the compiler instead of the destructor.
So a C # destructor does not run right after the object is no longer needed, nor is it executed in the same thread , but in the thread garbage collector . There are a number of problems related to the finalization method that are not part of the scope of the question. Finalizers, even in the form of a destructor, should only be customized when the programmer fully understands all its implications.
I've placed it on GitHub for future reference.