Here's a slightly modified program that demonstrates the behavior more clearly:
class Foo
{
public int Value;
public Foo Next;
public Foo(int value) { this.Value = value; Console.WriteLine("Created " + this.Value); }
~Foo() { Console.WriteLine("Finalized " + this.Value); }
}
class Program
{
public static void Main(string[] args)
{
var foo = new Foo(0);
for (int value = 1; value < 50; ++value)
{
foo.Next = new Foo(value);
foo = foo.Next;
if (value % 10 == 0)
{
Console.WriteLine("Collecting...");
GC.Collect();
Thread.Sleep(10);
}
}
Console.WriteLine("Exiting");
}
}
On .NET 4.5, when I build in Debug mode AND target Any CPU or x86, I reproduce the behavior you're seeing: the instances aren't finalized until after "Exiting" is printed. But when I build in Release mode OR target x64 (even when building in Debug mode), the instances are finalized as soon as they're unreachable:
Created 0
Created 1
Created 2
Created 3
Created 4
Created 5
Created 6
Created 7
Created 8
Created 9
Created 10
Collecting...
Finalized 9
Finalized 0
Finalized 8
Finalized 7
Finalized 6
Finalized 5
Finalized 4
Finalized 3
Finalized 2
Finalized 1
Created 11
Created 12
Created 13
...
Why does this happen? I suppose only a CLR expert can tell us for sure, but here's my guess: the behavior depends on specific details of the machine code that the JIT compiler and optimizer happen to generate, details which vary based on the target instruction set and whether you're running in debug mode. (Furthermore, these details may well change in future versions of the runtime.) In particular, in the x86/Debug case, I think the first Foo(0) instance gets stashed in a register or stack variable that never gets overwritten in the rest of the method; this initial instance keeps the entire chain alive. In the x86/Release and x64 cases, I think that due to JIT optimizations, the same register or stack variable is reused for every instance, thus releasing the initial instance.
foo = new Foo()instead of assigning tofoo.Foo? By the way,Public Foo Foo;doesn't compile. - Blorgbeard