24

可能重复:
嵌套的 Try/Catch 块是一个坏主意吗?

目前我在 try catch 中使用 try catch ?当前的 senario 在我们的应用程序中需要它。

void MyFun()
{
    try
    {
        //Process logic 1
        // ......
        try
        {
            //Process logic 2
            // ......
        } catch (Exception ex)
        {
            //write an error details in database
        }

        //Process Logic 3
        // ......

    } catch (Exception ex)
    {
        //show error msg
    }
}
4

7 回答 7

17

这没有什么特别的问题,特别是如果您想以不同的方式处理异常。
但是,如果内部异常和外部异常分别属于不同的类型E1, E2并且E1不是 的父级E2,则可以有两个相邻的 catch 子句。

try
{
  // do something
}
catch (E1 e1)
{
}
catch (E2 e2)
{
}

正如 Rob 和 J.Steen 所指出的 - 这与问题中的情况略有不同,因为在这种情况下E1,代码在不会被执行后被抛出。

于 2012-12-07T08:57:11.817 回答
2

嵌套的 try/catch 很好。您要远离的是基于 try catch 更改代码的逻辑流程。换句话说,您不应该将 try/catch 视为 if/else 块。所以这并不理想:

//over the top example just to demonstrate my point

public bool IsNumberTen(int x)
{
    try
    {
        if(x > 10)
            throw new NumberTooHighException();
        else if(x < 10)
            throw new NumberTooLowException();
        else
            return true;

    }
    catch(NumberTooHighException)
    {
        return false;
    }
    catch(NumberTooLowException)
    {
        return false;
    }
}
于 2012-12-07T08:58:25.160 回答
1

我不明白为什么不。如果您在 catch 中有可能失败或引发需要处理的异常的逻辑,那么这是有道理的。

于 2012-12-07T08:57:34.860 回答
1

这个项目表明它不是一件坏事,你只需要以其他方式处理错误。

异常处理 try catch inside catch

于 2012-12-07T08:56:35.407 回答
0

在不知道这里有什么逻辑的情况下回答这个问题有点困难。当然,在性能方面,嵌套异常处理会产生更大的成本,但一般的经验法则是只捕获作为开发人员了解如何处理的异常。这与 TDD 的实践重叠,如果您有一组足够好的测试,您可以确定预期的异常应该在哪里,那么这将决定您的异常逻辑。

于 2012-12-07T08:57:16.773 回答
0

我会说:这还不错。它是否取决于您的程序,以及考虑到您的方法的逻辑和合同,这样的概念是否有意义。

编辑:我建议查看文章Exception Cost: When to throw and when not to。它概述了 CLR 中异常管理最昂贵的部分。

于 2012-12-07T08:57:20.250 回答
0

我正在尝试考虑您可能需要嵌套块的情况......也许如果您正在更改数据库并且您正在使用 try catch 作为虚拟事务,您可能想要尝试更新一些属性,但如果这会失败,但如果您实际提交数据库更新本身,也会捕获一个整体异常。

即使考虑到这一点,您也永远不需要这样做......像这样简单地将块堆叠在一起就足够了:

void MyFun()
{
    try
    {
        //Process logic 1
        // ......
    } catch (Exception ex)
    {
        //show error msg
    }
    try
    {
        //Process logic 2
        // ......
    } catch (Exception ex)
    {
        //write an error details in database
    }

}

还可能值得注意的是,如果您发现需要嵌套 try catch 块,那么可能有更好的方法来设计您的代码。

编辑: Itay 的答案也比嵌套好一些,尽管一旦你发现异常,它就不允许你继续进行。

希望这可以帮助!

于 2012-12-07T09:00:36.897 回答