编译器和运行时都不需要保证超出范围的本地实际上已经截断了其内容的生命周期。出于计算寿命的目的,对于编译器或运行时来说,对待它似乎不存在大括号是完全合法的。如果您需要基于大括号的清理,然后实施IDisposable并使用“使用”块。
UPDATE:
关于你的问题:“这是为什么不同的优化VS未经优化的建立”,那么,看看代码生成的差异。
未优化:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 28 (0x1c)
.maxstack 1
.locals init (class test.Foo V_0)
IL_0000: nop
IL_0001: nop
IL_0002: newobj instance void test.Foo::.ctor()
IL_0007: stloc.0
IL_0008: nop
IL_0009: call void [mscorlib]System.GC::Collect()
IL_000e: nop
IL_000f: call void [mscorlib]System.GC::WaitForPendingFinalizers()
IL_0014: nop
IL_0015: call string [mscorlib]System.Console::ReadLine()
IL_001a: pop
IL_001b: ret
} // end of method Program::Main
优化:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 23 (0x17)
.maxstack 8
IL_0000: newobj instance void test.Foo::.ctor()
IL_0005: pop
IL_0006: call void [mscorlib]System.GC::Collect()
IL_000b: call void [mscorlib]System.GC::WaitForPendingFinalizers()
IL_0010: call string [mscorlib]System.Console::ReadLine()
IL_0015: pop
IL_0016: ret
} // end of method Program::Main
显然,一个巨大的差异。显然,在未优化的版本中,引用存储在本地插槽0中,直到方法结束才会删除。因此,在方法结束之前,GC不能回收内存。在经过优化的版本中,引用存储在堆栈中,立即从堆栈弹出,并且GC可以自由回收它,因为堆栈上没有有效的引用。
好的。这解释了很多。谢谢。 – 2009-11-11 16:42:12
极好的更新到您的文章,埃里克。非常感谢! – 2009-11-11 17:03:28