Reputation: 399
Can a class's finalizer be used for anything else than freeing resources? I read that it is called when the GC wants to remove the object from memory, which is very inspecific (I can see why but that limits its usage). Is it possible to reliably use the finalizer to do logic that is supposed to happen when a variable goes out of scope? If the finalizer is not fit for this, how can it be achieved?
My idea is basically the same as a destructor of an object that in c++ would be allocated on the stack, therefore its destructor has to be called when it goes out of scope. Or is there a way to force an object into the stack, so that it would behave the same way? Or maybe a using(...)
block and the dispose-related methods can be used to achieve something like this?
Upvotes: 1
Views: 329
Reputation: 23228
In C# you don't need to use the finalizer directly. It's being called by GC to clean up only unmanaged resources, if any. Technically, the finalizable object is added to a separate queue and being finalized in a separate thread before being garbage collected. However, it's a vary basic flow and you don't have to rely on it.
Eric Lippert has written two very nice articles about finalizers under the hood, this and this, refer to them to see a possible pitfalls here. Finalizers are called in a non-deterministic order, you should never perform any logic depends on other objects inside finalizer.
For you purposes you can implement IDisposable
interface and clean up the resources explicitly, have a look at MSDN guide for details.
The very simple sample is below
public class MyResource : IDisposable
{
// managed resource this class uses.
private readonly Component _component = new Component();
private bool _disposed;
public void Dispose()
{
if (!_disposed)
{
// Dispose managed resources.
_component.Dispose();
_disposed = true;
}
//tell CLR to prevent finalization, since it's already done
GC.SuppressFinalize(this);
}
}
If your class wraps only managed resources, you don't need to use a finalizer, you just implementing a Dispose()
method to clean up a managed resources.
Object, implementing IDisposable
, can be used in using
statement, or in try/finally
block, according to using an object that implements IDisposable
Upvotes: 1
Reputation: 6234
Besides the posted links, you are going against the design and you might end up in a lot of weird things if you keep on going this road.
If you want to replicate c++ RAII behavior, just use the using
keyword with disposable resources.
C# 8 introduce the ability to declare using var
variables,just syntactic sugar that syntactically make the code as closest as possible to c++ RAII.
Eric Lippert links explain what's going on under the hood, clearly this gives you an insight, but nothing there is contractual when leaving the designed road.
Upvotes: 1