Answer to this poser
I wasn't sure the answer to this question was observable, so I wrote a short program:
using System; class Early { ~Early() { Console.WriteLine("Early Cleaned Up"); } } class Test { public static void Main() { Early e = new Early(); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine("Done Waiting"); } }
The output from this is
Early Cleaned Up Done Waiting
In other words, there is no guarantee that a local variable will remain live until the end of a scope if it isn't used. The runtime is free to analyze the code that it has and determine what there are no further usages of a variable beyond a certain point, and therefore not keep that variable live beyond that point (ie not treat it as a root for the purposes of GC).