簡體   English   中英

在try catch塊中為IDisposable使用塊有什么問題嗎?

[英]Are there any issues with using block for an IDisposable within a try catch block?


MSDN建議將實現IDisposable的類的任何實例化放入using塊。 或者,如果它在try-catch塊中實例化,則Dispose in Finally

try-catch塊中using塊是否有任何問題?

try
{
    using (Foo bar = new Foo())
    {
       bar.doStuff();
    }
}
catch (Exception e)
{
    //vomit e
}

當然我可以在Finally一個塊中調用Dispose ,但我是編程的新手,我只是想知道做這樣的事情是否實際上是可以接受的,或者是否有人會打我的后腦和大喊在我身上,我在Doing-It-Wrong™

或者更確切地說,我更有興趣知道為什么會出現這種錯誤。

不,這看起來很好。 你的酒吧實例將在你進入catch區塊之前被處理掉。

這是...... 滾筒 ......絕對沒問題。

唯一的問題是你不應該使用catch (Exception) ,但要捕獲你感興趣的特定錯誤(即使這只是一個例子),但這與using無關。 事實上,你為什么會把唯一的理由using外部try塊,是因為你要繼續做的東西bar這是無關的是失敗的碼-否則,保持范圍盡可能小通常是一個好主意。

沒關系,但是你失去了在異常中導致異常的對象的訪問權限。
捕捉一般例外不被視為一種好的做法

Foo bar = null;
try
{
    bar = new Foo();
    bar.doStuff();
}
catch (IndexOutOfRangeException e)
{
    //vomit e
    Debug.WriteLine(e.msg);
    if(bar == null) 
       Debug.WriteLine("bar = new Foo() failed ");
    else 
       Debug.WriteLine("bar fail ID = " + bar.ID);
}
catch (Exception e)
{
    // ...
    // unless you are going to handle it gracefully you should rethrow it
}
finally 
{
    if(bar != null) bar.Dispose();
}

您的示例代碼是多余的。 Using()文檔說明

表格的使用聲明

using (ResourceType resource = expression) 

聲明對應於兩種可能的擴展之一。 當ResourceType是值類型時,擴展為

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      ((IDisposable)resource).Dispose();
   }
}

否則,當ResourceType是引用類型時,擴展為

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

在任一擴展中,資源變量在嵌入語句中是只讀的。

您的代碼最終將如下所示:

try
{
    Foo bar = new Foo()
    try
    {
       bar.doStuff();
    }
    finally 
    {
       if (bar != null) ((IDisposable)bar).Dispose();
    }
}
catch (Exception e)
{
    //vomit e
}

兩個嘗試聲明沒有真正的理由。 這不是錯誤的代碼,它在多個try語句的上下文中是多余的。 您的問題似乎是關於Disposing對象。 在這種情況下,它是多余的。 如果您還擔心拋出異常的對象構造函數,顯然需要這樣做。

在try-catch塊中使用using塊是否有任何問題?

不,我一直在寫你的例子。

當然我可以在Finally塊中調用Dispose,

排序,必須在try / catch之外調用構造函數,否則在到達finally塊時變量將超出范圍

有效:

var foo = new bar();
try
{
}
finally
{
  foo.Dispose();
}

無效:

try
{
  var foo = new bar();
}
finally
{
  foo.Dispose();
}

不,這很好,但如果你想在catch期間訪問bar ,你需要一個內部try catch

try
{
    using (Foo bar = new Foo())
    {
      try
      {
        bar.doStuff();
      }
      catch (Exception e)
      {
        //vomit e, with bar available.
      }
    }
}
catch (Exception e)
{
    //vomit e, relating to a problem during creation of Foo.
}

或者,如評論中所建議的,將內部塊分解為新方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM