【问题标题】:Return in catch block?在 catch 块中返回?
【发布时间】:2011-02-11 00:22:19
【问题描述】:

在 catch 块中有 return 语句是错误的吗? 有哪些选择?
即:

public bool SomeFunction()
{
    try
    {
        //somecode
        return true;
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.message);
        return false;
    }

}

【问题讨论】:

标签: c# .net exception-handling


【解决方案1】:

你可以从 catch 块中正常返回。 它通常是很好的功能代码。

【讨论】:

    【解决方案2】:

    另一种方法是将返回值存储在临时变量中:

    public bool SomeFunction()
    {
        bool success = true;
        try
        {
            //somecode
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.message);
            success = false;
        }
    
        return success;
    }
    

    但就个人而言,我发现您编写它的方式(使用一个包罗万象的 catch 语句)更具可读性。另一方面,如果您期待一个特定的异常,并且您可能有多个返回成功或不成功的路径......

    try
    {
        DoTheImportantThing();
        DoTheOtherThingThatMightFailButWeDontCare();
    }
    catch (DontCareAboutItException ex)
    {
        log.Info(ex);
    }
    catch (Exception ex)
    {
        log.Error(ex);
        return false;
    }
    
    return true;
    

    那么在我看来,你最好将 return 语句尽可能地推到最后。

    附带说明一下,根据应用程序,考虑记录您捕获的异常,而不是仅仅将它们显示给用户。记录的异常比用户对所发生事件的叙述要可靠得多。

    【讨论】:

      【解决方案3】:

      如果在 try 块中已经有一个 return 语句,我可能会将另一个 return 放在函数的末尾:

      try
      {
          //somecode
          return true;
      }
      catch(Exception ex)
      {
          MessageBox.Show(ex.message);
      }
      return false;
      

      这是为了避免在需要处理多个异常时多次返回。

      【讨论】:

      • 如果我遵循将 return 放在 catch 中的模式,那么如果在重构过程中我不小心删除了 try 中的 return 语句,编译器会提示我出错。但是如果我在 catch 之后继续返回,那么代码将编译并且它可能最终会在 prod 中结束。
      【解决方案4】:

      没关系,请记住,有些代码可能会在返回指令之后执行(返回值将被兑现)。

          try
          {
              return;
          }
          catch(Exception ex)
          {
              return;
          }
          finally
          {
              //some code
          }
      

      【讨论】:

        【解决方案5】:
        public bool SomeFunction()
        {
            try
            {
                //somecode
                return true;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.message);
            }
            return false;
        }
        

        我个人将 return 语句放在方法的底部,而不是在 catch 块中。但两者都很好。一切都与您组织中的可读性(主观)和指导方针有关。

        【讨论】:

          【解决方案6】:

          是的,这完全正常。

          别忘了,你也可以使用 finally 块在返回后执行。

          【讨论】:

          • 因此代码将难以阅读,因为代码是在返回之后执行的。
          • 将 return 放在 catch 块中可能难以阅读,因为您希望 return 绕过 finally 语句。将 return 块放入 try 块中也是如此。 Return 通常意味着“方法中的所有执行都停止,控制权返回给调用者”,而 finally 块总是在离开 try/catch 时运行,因此预测哪个优先并不容易。
          【解决方案7】:

          没有错,但是如果你使用了一个资源,一般都会用 finally 块来关闭它,而不是调用两次 close 方法。在这种情况下,您可以选择在 finally 块之后使用 return 语句。

          【讨论】:

          • finally 即使在 try 块中返回,仍会执行。
          • 在这种情况下,finally 块之后的 return 语句只会造成混乱。它会起作用,但最好不要使代码复杂化(太多)。
          【解决方案8】:

          对于成功返回 true 失败返回 false 的函数对我来说非常有意义。我希望它没有任何问题 - 我一直都这样做:)

          【讨论】:

            【解决方案9】:

            您可以在 catch 块中添加return。您明确知道您的代码将返回并继续执行,而不是在 catch 块处停止。

            try{
                //do something
            }
            catch{
                //error handling
                return;
            }
            

            与其在您的代码中包含大量可能会令人困惑并导致代码混乱的 try-catch 块,不如处理您的 noe try catch 中的所有内容并检查返回的错误是什么。

            try{
                //do something
            }
            catch (Exception as err){
                if (err == "IOException"){
                     //handle exception
                else if (err.indexOf("TypeError"){
                     //handle exception
                }
            }
            

            这是检查异常类型的两种方法,以便您可以相应地显示消息。如果你愿意,你也可以只捕获特定的异常,而不是Exception as err,你可以做catch IOException, ...

            【讨论】:

              【解决方案10】:

              catch 块的主要目的是提供一个地方,让人们可以处理发生在 try 块中的异常情况。所以你发现了一个异常,继续它......并从一个方法返回。如果调用者方法不关心异常,这是绝对正常的。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2017-05-15
                • 1970-01-01
                • 2020-12-23
                • 2012-05-18
                • 2016-05-06
                • 1970-01-01
                • 2019-08-31
                相关资源
                最近更新 更多