考慮,是否有可能引用GC'd目前正在被`using`塊使用?
using (var abc = new Abc())
{
// abc is not used here at all.
}
是否有可能在ABC的垃圾結束大括號之前收集的?
考慮,是否有可能引用GC'd目前正在被`using`塊使用?
using (var abc = new Abc())
{
// abc is not used here at all.
}
是否有可能在ABC的垃圾結束大括號之前收集的?
沒有。在內部,有一個參考文件持有到abc
,直到結束大括號。
生成的IL代碼如下所示:
IL_0001: newobj instance void ConsoleApplication1.Abc::.ctor()
IL_0006: stloc.0
.try
{
IL_0007: nop
IL_0008: nop
IL_0009: leave.s IL_001b
} // end .try
finally
{
IL_000b: ldloc.0
IL_000c: ldnull
IL_000d: ceq
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: brtrue.s IL_001a
IL_0013: ldloc.0
IL_0014: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0019: nop
IL_001a: endfinally
} // end handler
當using
語句在轉向IL代碼時,編譯器實際上翻譯的是一個完整的try/finally
塊,並調用.Dispose()
方法對您的實例Abc
。所以基本上是把它變成類似:
Abc abc = new Abc();
try
{
}
finally
{
abc.Dispose();
}
沒有,它的範圍是從開括號來的using
和lock
塊右括號。因此,在這兩個大括號之間它是非常多的,不管你是否使用垃圾收集。
+1後我的編輯:)。請注意,普通{}塊不具有此行爲。 –
@AlexeiLevenkov:從我+1到您的評論。 –
'使用'塊有絕對的**沒有任何**垃圾收集。 –
@KirkWoll,它的確有點用 - 在'using'中使用的對象的生命週期被擴展了(由rally25rs解釋),不像普通的{}塊,其中開始使用的對象可以在塊的中間被GC化。顯然這是因爲對象實際上是在塊外部使用的,但是需要對這兩種機制都有很好的理解才能做到正確。 –
@AlexeiLevenkov,對任何使用表達式('lock','foreach'等)的塊語句都可以這麼說。在所有情況下,這個陳述本身都是在這個塊的持續時間內表達的,但我認爲這是一個真正的延伸,說這是某種意義上的這種陳述*特別是*有關垃圾收集的任何話。 –