This is complicated, but simple, all at the same time.
The simple version?
The destructor is only called for unreferenced objects, and the third item you created is still referenced: the local variable
c
still contains it.
To prove that, kill the reference inside the loop:
static void Main(string[] args)
{
for (int i = 0; i < 3; i++)
{
Class1 c = new Class1();
c = null;
}
GC.Collect();
Console.ReadLine();
}
And you will get three calls to the destructor.
The complicated bit is that you think the variable
c
has been dereferenced - but it hasn't been, it's just gone out of scope.
That's not the same thing: the variable is allocated on the stack when the method is called, not when it is declared (so that regardless on the path through the method the number of stacked items to be removed is the same) so scope doesn't effect actual existence!
That's actually worth remembering: if you need a lot of variables (or some really big
struct
s) in a single route through the method but not in others and stack space is at a premium the it's worth moving that path outside the method and into it's own ...
(But remember that an array of anything is a reference value, so it's on the heap anyway, except for the variable which references the array itself.)