![](/img/trans.png)
[英]Using try/catch makes it so I can't use the variable outside of the try/catch block
[英]Should try/catch be inside or outside a using block?
using
塊是try/catch/finally
簡寫,我相信。 在我的代碼,我一直把一個try/catch
塊里面 using
塊,這樣我就可以用我自己的記錄器捕獲和記錄異常。
我最近一直想知道是否應該在外面進行try
,從而封裝了using
塊。
在我看來,我以前一直擔心如果拋出異常,那么using
塊將不會Dispose()
我的資源,因為它跳出了塊並進入了catch處理程序。 但我可能錯了。
有人可以澄清一下using
和try/catch
一起使用的正確方法是什么?
public HttpResponseMessage GetData(string x, int y)
{
using (var client = new HttpClient())
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
}
這實際上取決於您擔心被處置的資源 - 如果您指的是client
您應該沒事。 我會解釋為什么......
在我看來,我以前一直擔心如果拋出異常,那么using塊將不會Dispose()我的資源,因為它跳出了塊並進入了catch處理程序。 但我可能錯了。
這不是它的工作原理,編譯器可能會重寫你的代碼(可能更有效),如下所示:
try
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
finally
{
if (client != null)
client.Dispose();
}
在正常情況下, finally
塊將始終執行,這意味着,即使您在using
捕獲/重新拋出異常,也會觸發Dispose
調用。
因此從技術角度來看,內部與外部並不重要。
using
塊用於確保一旦代碼超出using
塊,就可以確保在using
語句中聲明的對象處理(從詹姆斯先生建議的不明確的“立即處置”術語改為處置)。 它不完全是try/catch/finally
的簡寫。 (請注意, 編譯器會將其解釋為try-finally )
在你的例子中
using (var client = new HttpClient())
{
} //client will be disposed at any time after this line
根據具體情況,您可以考慮將try-catch
塊放在using
塊的內部或外部。
例如,如果您不需要多次using
聲明中的項目(編輯:我的意思是,如果您在try
和catch
塊中都需要該項目 - 感謝Cody Gray先生的輸入) -也就是說,你只需要它try
,我會建議使用using
的內部塊try
塊。
轉換為您的情況,它取決於var client
是否同時用於try
和catch
塊。 如果是,則using
應該在try-catch
塊之外。 否則,它應該在try
塊內。
通常,根據經驗,如果在try
和catch
塊中同時使用該項,則在try-catch
外部僅聲明一次using
無論哪種方式都可行。 保證使用塊總是在退出時調用Dispose()
方法 - 即使對於堆棧的進一步向下捕獲異常的堆棧,也是如此。
using語句確保即使在對象上調用方法時發生異常,也會調用Dispose。 您可以通過將對象放在try塊中然后在finally塊中調用Dispose來實現相同的結果; 實際上,這就是編譯器如何翻譯using語句。 前面的代碼示例在編譯時擴展為以下代碼(注意額外的花括號以創建對象的有限范圍):
沒有“正確的方法”,只有指導方針。 然而,我自己嘗試盡可能地將每個異常或任何代碼本地化,這意味着你應該拋出一個異常,但是在外面的某個地方,至少只要你不必讓你的異常通過不同的層泡。
就個人而言,我會將try / catch / finally放在using
塊中。
這樣做的原因很簡單,即using
塊本身不會拋出異常,至少不是根據我的經驗。 所以為了簡單起見,我會處理它們發生的異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.