views:

131

answers:

2

Is it legal to write the following in .net ?

   public class A
    {
        public int i = 0;
        ~A()
        {
            Aref = this;
        }
    }


    public static A Aref;
    static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Aref.i);
        Console.ReadLine();
    }

It works and writes '0' to the console as expected, but I'm wondering if it's guaranteed to always work.

Does someone know what's happening behind the scene?

+8  A: 

It's called resurrection, and it's legal. Google for ".net object resurrection" (and terms like it) and you'll find stuff like:

Resurrection and the .NET Garbage collector

Object Resurrection

Just make sure these zombie objects don't come back and try to eat your brain or something. Like all necromancy, this is dangerous stuff. (Mostly because the finalizers higher up in the class hierarchy can have released some essential resource. Also note that the finalizer won't be run a second time if the object gets "unreferenced", unless you call GC.ReRegisterForFinalize .)

gustafc
Hmm, I thought resurrection only goes for WeakReferences.
leppie
+1  A: 

It works because the first garbage collection doesn't collect the instance. It just schedules the instance to have its finalizer run. The finalizer then creates a new root to the instance, so when the next collection happens the instance is actually rooted and thus not up for collection.

You should be very careful with this tough. If the finalizer is used to make sure an object is disposed, this actually violates the protocol because the disposable patterns says that a disposed instance should throw an ObjectDisposedException if it is used after being disposed.

Brian Rasmussen
I heard there may (or may not) also be some possible issues with this approach if you throw an exception in the constructor as a security check ;-p [runs for cover...]
Marc Gravell
You shouldn't listen to people who say something like that :)
Brian Rasmussen