【问题标题】:Is it bad practice to nest 2 try catch statements in C#?在 C# 中嵌套 2 个 try catch 语句是不好的做法吗?
【发布时间】:2009-09-21 18:15:57
【问题描述】:

以下代码是不好的做法吗?

 try //Try Overall Operation
      {
           try //Try section 1 of operation
               {

               }
           catch(exception ex)
               {
                    //handle exception code
                    //throw the exception
       }
 catch (exception ex)
      {
          // send soap exception back to SOAP client.
      }

我知道,从程序审查的角度来看,其他开发人员看到 2 次尝试像这样直接嵌套可能会想知道为什么,但这完全是禁忌,还是现在已被接受?

谢谢伙计们,我同意你们关于重构的所有观点,将为子功能创建一个单独的方法,该方法变得非常长。我对所有选择这个的人印象深刻......

【问题讨论】:

标签: c#


【解决方案1】:

没有。我认为这根本不是坏习惯。

如果您在第一个嵌套尝试中做某事,您可以正确捕获和处理,这非常好,尤其是当您在两个处理程序中“捕获”不同类型的异常时。

但是,我会说这是可能重构的好机会,并将嵌套部分拆分为单独的方法。通常,当我看到这一点时,这表明该方法应该被拆分为更小的方法。然而,这并不总是正确的。

【讨论】:

  • +1 用于将嵌套的 try/catch 块重构/分离为它们自己的方法。
  • 很高兴你得到了赞成票,但有些莳萝无缘无故地反对我,因为他们不懂英语。
  • 嘿,我也投了反对票。不幸的是,这是 SO 体验的一部分。有时,我希望您必须发表评论才能投反对票,因为我想知道人们为什么不同意。
  • 任何重构示例??
  • @alhambraeidos:基本上,它只是将内部操作提取到一个单独的方法中。 (不知道它的作用,很难对名字做出合理的猜测......)
【解决方案2】:

在我看来,不必如此。有时您希望在第一次尝试中执行某些代码,即使第二次尝试中的代码失败。

还可以补充一点,其他人所说的也是正确的。我只是说它不一定总是坏的。在对性能要求不高的程序中,您可以随心所欲地进行操作。

【讨论】:

    【解决方案3】:

    这取决于您的程序需要做什么。通常最好将您的try/catch 包裹在尽可能小的工作范围内,并尽可能缩小异常处理的重点,以避免意外行为、副作用或错误。很多时候,这意味着拥有一系列 try/catch 块,这很好。

    【讨论】:

      【解决方案4】:

      我认为这取决于您如何处理内部异常。您的内部捕获需要做一些与外部捕获范围完全不同的事情,这可能是非常合乎逻辑的。您要避免的一件事是将内部异常隐藏为外部异常的原因。换句话说,我强烈推荐

      try
      { 
           // Do something 
           try
           {
               // Do something
           }
           catch(MyException e)
           {
               // handle
               throw; // <--- This is important, it rethrows the same exception while maintaining the stack trace.  This is *different* from "throw e"
           }
      }
      catch(AnotherException e)
      {
          // handle 
      }
      

      【讨论】:

      • @astander - 当且仅当实际抛出异常时才会消耗性能。因为异常毕竟是异常的,所以这在大多数代码中应该不是问题。
      • 这是真的,但如果处理得当,这种情况应该很少发生,所以我建议在接受异常覆盖作为首选方法之前通过检查来处理异常。检查你的参数,检查你的文件是否存在,在假设之前检查你的集合中有对象
      【解决方案5】:

      只要逻辑允许,这不是坏习惯。

      例如,如果最外层的try 用于捕获SQL 异常,而最内层的try 用于IO 异常,那么这样做可能是合理的。

      但是,请注意避免使用涵盖大量代码行的包罗万象的 try 子句。 那些不是好习惯。

      【讨论】:

        【解决方案6】:

        不,不一定是坏形式。

        就像大多数这类问题一样(即 goto 是邪恶的吗?,是 for(;;) 邪恶的吗?)这些东西有它们的位置,如果在需要时使用它们是可以的。

        【讨论】:

          【解决方案7】:

          如果您可以在第一个 try 块中处理异常并仍然成功继续,我认为它没有任何问题。如果只是为了做某事并重新抛出,只需为您正在寻找的特定类型的异常添加另一个 catch 块并在那里处理它。

          【讨论】:

            【解决方案8】:

            这并不可怕,但是看看你是否不能通过根据需要处理异常类型来解决这个问题:

            try
            {
            
            } 
            catch (SqlException ex )
            {
            // Catches specific exception
            }
            catch ( Exception ex )
            {
            // Catch-all
            }
            

            每次您执行 try-catch 时,您都会创建另一个妨碍可读性的语句线程。例如:

            try
            {
               try
               {
               }
               catch ( Exception ex )
               {
               }
            }
            catch ( Exception ex )
            {
            }
            

            【讨论】:

            • "每次你做一个 try-catch 你都在创建另一个线程。"我不认为这是正确的。
            • try-catch 和线程数之间没有相关性。 [注意:我不是投反对票的人]
            • @Alex:你永远不应该“投票补偿”,因为它是错误的,所以被否决了,希望作者能意识到这一点并删除它。
            • @Nissan Fan:我理解你的意思,但是“线程”是一个不好的术语选择——“线程”有一个特定的含义,这不是你所说的。在这种情况下,每次添加 try/catch 时,都会添加另一个“指令路径”或“执行路径”会更好。如果你说线程,你就是在暗示多线程,不管你说“线程”还是“线程”——对于大多数程序员来说,两者的含义都是一样的。
            • @Nissan 抱歉,您被误解了。请意识到几乎所有开发人员都使用“线程”来表示一件事:en.wikipedia.org/wiki/Thread_%28computer_science%29 ... 在另一个上下文中使用它显然会导致混淆。
            猜你喜欢
            • 2010-10-14
            • 2012-05-27
            • 1970-01-01
            • 2022-07-11
            • 1970-01-01
            • 1970-01-01
            • 2016-04-13
            • 1970-01-01
            • 2010-10-01
            相关资源
            最近更新 更多