在finally块中使用try/catch是否可行?

5

这是一个“好”的代码吗?

        try
        { /*stuff*/ }
        catch (Exception e)
        { /*stuff*/ }
        finally
        {
            try
            { /*stuff*/ }
            catch { /*empty*/ }
        }

我需要在finally中执行复杂操作,由于它正在连接数据库,可能会崩溃。

这看起来很奇怪。这是正确的方法吗?


6
如果你有医疗条件,服用药物是否可以?让我们填补这里的空白。在 finally 中使用 try/catch 的概念本身没有问题,但具体情况取决于你想要做什么以及你的终极目标是什么,可能会出现问题。 - corsiKa
你能简要告诉我们你在 finally 中打算做什么吗? - Purplegoldfish
1
取决于异常类型和您打算如何处理它。最少应将finally块的主体抽象为一行代码。 - wberry
对我来说,这似乎有点像是代码异味... 也许你finally块中的代码应该放在另一个函数中。 - Richard Ev
一句话 - 哎呀、哇塞和天哪! - JonH
5个回答

3

这真的取决于你在做什么,但就个人而言,如果它确实是在其他try catch之后并在操作完成后完成,我不会将其嵌套在finally中,只需将其视为另一个try catch即可。这将消除其中一些“怪异性”。


这让我重新审视整个代码,事实上你是对的,在我的情况下,最好删除 finally 并在原始 try/catch 后添加另一个 try/catch。 - Fredou

1

从惯用语的角度来看,你会这样做:

try
{
    /* stuff */
}
catch 
{
    /* stuff */
}
finally 
{
    DoStuff();
}


void DoStuff()
{
    try 
    {
        /* stuff */
    }
    catch
    {
        /* stuff */
    }
}

这没有任何意义,我不明白它如何解决问题,而且也不是一个理想的情况。我认为两个try catch语句应该在它们自己的方法中,被一个方法调用,在另一个方法之后。这些方法应该返回一个值。 - Security Hound

1

嵌套的try/catch块并不理想,但在某些情况下是必要的。只需确保正确处理任何错误即可。


0
通常情况下,当一个异常正在处理时抛出另一个异常,会导致第一个异常被第二个(后来的)异常替代。
以下是一段代码,用于说明发生的情况:
    public static void Main(string[] args)
    {
        try
        {
            try
            {
                throw new Exception("first exception");
            }
            finally
            {
                //try
                {
                    throw new Exception("second exception");
                }
                //catch (Exception)
                {
                    //throw;
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

运行代码,您会看到“第二个异常”。 取消 try 和 catch 语句的注释,您将看到“第一个异常”。 同时取消 throw; 语句的注释,您将再次看到“第二个异常”。

0

是的。在 finally 中抛出异常会隐藏原始异常。这类似于建议不要在创建代理时使用 WCF,尽管这本身是另一个讨论。

这将输出 B 而不是 A:

static void Main(string[] args)
    {
        try
        {
            try
            {
                throw new ApplicationException("A");
            }
            finally
            {
                throw new ApplicationException("B");
            }
        }
        catch (Exception e)
        {

            Console.WriteLine(e.Message);
        }
        Console.Read();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接