2012-06-26 22 views
1

考慮,是否有可能引用GC'd目前正在被`using`塊使用?

using (var abc = new Abc()) 
{ 

    // abc is not used here at all. 

} 

是否有可能在ABC的垃圾結束大括號之前收集的?

+1

'使用'塊有絕對的**沒有任何**垃圾收集。 –

+1

@KirkWoll,它的確有點用 - 在'using'中使用的對象的生命週期被擴展了(由rally25rs解釋),不像普通的{}塊,其中開始使用的對象可以在塊的中間被GC化。顯然這是因爲對象實際上是在塊外部使用的,但是需要對這兩種機制都有很好的理解才能做到正確。 –

+2

@AlexeiLevenkov,對任何使用表達式('lock','foreach'等)的塊語句都可以這麼說。在所有情況下,這個陳述本身都是在這個塊的持續時間內表達的,但我認爲這是一個真正的延伸,說這是某種意義上的這種陳述*特別是*有關垃圾收集的任何話。 –

回答

5

沒有。在內部,有一個參考文件持有到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(); 
} 
2

沒有,它的範圍是從開括號來的usinglock塊右括號。因此,在這兩個大括號之間它是非常多的,不管你是否使用垃圾收集。

+1

+1後我的編輯:)。請注意,普通{}塊不具有此行爲。 –

+0

@AlexeiLevenkov:從我+1到您的評論。 –

相關問題