編譯器和運行時都不需要保證超出範圍的本地實際上已經截斷了其內容的生命週期。出於計算壽命的目的,對於編譯器或運行時來說,對待它似乎不存在大括號是完全合法的。如果您需要基於大括號的清理,然後實施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