-->

使用的最后,而不是抓(Using finally instead of catch)

2019-09-17 10:44发布

我已经看到了这种模式现在几次:

        bool success = false;
        try
        {
            DoSomething();
            success = true;
        }
        finally
        {
            if (!success)
                Rollback();
        }

我一直在想:为什么这比使用渔获回滚更好?

        try
        {
            DoSomething();
        }
        catch
        {
            Rollback();
            throw;
        }

什么是确保更改将回滚失败的两种方法之间的差异?

Answer 1:

这里的明确目标是使Rollback到任何错误的情况下被调用。 这两个代码段实现这一目标。 第一次使用了最后,这始终运行,用来验证的最后一行try块顺利到达。 所述第二捕获任何错误,回滚事务,然后重新抛出这是捕捉到的异常。 无论是代码片段的结果是,抛出的异常会导致回滚,同时仍然向上冒泡到一个新的水平。

你提到的项目是从Java移植。 在Java中,你可以 重新抛出异常类似于您如何在C#中使用throw; 。 您也可以抛出一个新的异常 ,将仍然保持调用堆栈(等人)。 第二个是有点清晰/ C#中简单的(不是很多,虽然)和第一有在Java中实际工作书面的优势。



Answer 2:

我在这里发布,即使它没有真正涉及到的问题(稍后会删除)一些代码。

有了这个程序:

using System;

namespace testcs
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                try
                {
                    foo();
                    foo();
                    foo();
                }
                catch
                {
                    throw;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void foo()
        {
            throw new Exception("oops");
        }
    }
}

堆栈跟踪(看行号!)是保留的,但里面main功能,你会看到“第19行”,其中线throw是不是行,其中foo()被调用(13号线)。



Answer 3:

finally陈述通常用于清理资源。 该Rollback()如果异常是不可回滚事务的唯一原因,方法可能是正确的使用存在。 Close()Dispose()的方法是总理候选人在finally块结束。

但是,你不想在那里执行任何可以抛出异常。



Answer 4:

如果没有什么类型的异常,你正赶上使用这个特殊的代码护理:

try
{
   DoSomething();
   ok = true;
}
finally
{
    if(!ok)Rollback();
}

这将在其原来的形式为100%保留调用堆栈。 此外,如果你使用异常MACHING这样的:

try
{
   DoSomething();
   ok = true;
}
catch(FirstExcetionType e1)
{
    //do something
}
catch(SecondExcetionType e2)
{
    //do something
}
catch(Exception e3)
{
    //do something
}
finally
{
    if(!ok)Rollback();
}

使用最后在年底可以使你的代码不是从每一个catch语句调用回滚更具可读性。



Answer 5:

我不知道这是不是只是传闻 ,但我个人已经使用这种模式的一个很实际的理由:当DoSomething抛出一个异常,Visual Studio调试器将打破DoSomething在异常的第一个版本出现,而这将打破在throw; 在第二个版本。 这允许检查应用程序状态之前Rollback一切都已经清理干净。



Answer 6:

finally总是执行,不仅捕捉异常。

当然,在这种特殊情况下,当出现错误回滚时,才需要,但作为一个普通模式, try-finally可能是资源管理更加有用(其中往往你需要确保你总是Close()Dispose()你的资源的正确)。 特别是如果代码的作者是从Java背景的,其中这个成语是更为普遍。



文章来源: Using finally instead of catch