2012-04-03 22 views
6

我想純粹使用using語句來進行範圍管理。我可以省略明確引用實現IDisposable的基礎對象嗎?我可以在RHV(右手價值)中使用使用語句嗎?

例如,給這個declaraions:

class ITransactionScope : IDisposable {} 
class TransactionGuard : ITransactionScope {...} 

class DbContext 
{ 
    public IDisposable ITransactionScope() 
    { 
     return new TransactionGuard(); 
    } 
} 

我能做到以下幾點:

void main() 
{ 
    var dbContext = new DbContext(); 

    using (dbContext.TransactionScope()) 
    { 
     // the guard is not accessed here 
    } 
} 

期間using語句TransactionGuard實例還活着嗎?

+0

你可以試試。在返回的作用域實例的Dispose()方法中設置一個斷點並查看它是否被調用。 – linuxuser27 2012-04-03 15:31:40

+0

我真的希望你可以,因爲我使用相同的策略,它的工作原理:) – 2012-04-03 15:31:50

+3

如果你關心的只是範圍管理,你不能只在代碼中加上大括號(沒有「使用」),那將是明確的代碼裏面的範圍? – 2012-04-03 15:40:23

回答

10

我想純粹用於範圍管理的using聲明。

您應該使用using聲明來說明它的目的:及時處理非託管資源。如果這不是你用的using,你可能做錯了什麼。

我可以省略顯式引用實現IDisposable的基礎對象嗎?

另一個答案指出:你已經輸入了代碼;你可以簡單地嘗試它。

是的,你可以做到這一點。編譯器會爲你創建一個不可見的局部變量,並且在其上調用Dispose

我建議如果您有關於使用using的更多問題,請閱讀C#4規範的第8.13節。

+0

你能看看我的答案嗎? GC不會回收它嗎? – Aliostad 2012-04-03 15:39:46

+0

@Aliostad:C#規範聲明'using(expr)s;'完全等價於'X temp = expr;嘗試{s; } finally {if(temp!= null)((IDisposable)temp).Dispose();}'。你聲稱垃圾收集器會在調用Dispose之前清理temp *嗎? – 2012-04-03 15:45:26

+0

@Eric也許你可以與MVC團隊討論濫用C#功能。 ;)雖然我不介意這個;這是一個方便的語法,它不使用反射。 – 2012-04-03 15:46:01

2

它是活着的,直到你處置它。所以,是的。

而這種類型的問題更容易讓你通過點擊編譯和運行按鈕來回答。你已經輸入了密碼。嘗試一下。

+1

-1。這不一定是真的。你可能會嘗試它的工作100次,但不是最後一次。 – Aliostad 2012-04-03 15:32:35

+5

@Aliostad:我沒跟着你。批評似乎完全有理由;這個問題本可以通過簡單地嘗試,或者甚至更好地通過閱讀文檔然後嘗試來輕鬆解決。你能給我一個程序的例子,其中一個使用語句連續工作一百次後失敗了嗎? – 2012-04-03 15:41:07

+0

@EricLippert我的觀點是GC可能會在使用'statement'結束之前回收它。因此我的回答是,如果你能回顧一下,我將不勝感激。 – Aliostad 2012-04-03 15:42:43

相關問題