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).