将尝试/最后(没有Catch)冒泡例外?

我几乎肯定答案是肯定的。 如果我使用Try Finally块,但不使用Catch块,则任何exception都会冒泡。 正确?

一般的做法的任何想法?

赛斯

是的,它绝对会。 假设你的finally块不会抛出一个exception,当然,在这种情况下,这将有效地“取代”最初抛出的exception。

一般的做法的任何想法?

是。 小心点 当你的finally块正在运行时,它完全有可能正在运行,因为一个未处理的意外的exception已经被抛出 。 那意味着某些东西被打破了完全出乎意料的事情可能会发生。

在这种情况下,可以certificate你不应该在最后的块中运行代码。 finally代码块中的代码可能会被假设为假设它所依赖的子系统是健康的,而实际上它们可能会被深深打破。 finally块中的代码可能会让事情变得更糟。

例如,我经常看到这样的事情:

 DisableAccessToTheResource(); try { DoSomethingToTheResource(); } finally { EnableAccessToTheResource(); } 

这段代码的作者正在思考:“我正在暂时地改变世界的状态,我需要把状态恢复到以前的状态”。 但是让我们想一想,这可能会出错。

首先,调用者已经可以禁止访问资源; 在这种情况下,这个代码可能会过早地重新启用它。

其次,如果DoSomethingToTheResource抛出一个exception,是否可以访问资源是正确的? pipe理资源的代码意外地被破坏 。 这段代码说,实际上“如果pipe理代码被破坏, 确保其他代码可以尽快调用那个破坏的代码,这样它也可以失败 。 这似乎是一个坏主意。

第三,如果DoSomethingToTheResource引发exception,那么我们怎么知道EnableAccessToTheResource也不会抛出exception呢? 无论使用什么样的资源,都可能影响清理代码,在这种情况下,原来的exception将会丢失,问题将更难诊断。

我倾向于在不使用try-finally块的情况下编写这样的代码:

 bool wasDisabled = IsAccessDisabled(); if (!wasDisabled) DisableAccessToTheResource(); DoSomethingToTheResource(); if (!wasDisabled) EnableAccessToTheResource(); 

现在国家没有变化,除非需要。 现在来电者的状态不会被混淆。 而现在,如果DoSomethingToTheResource失败,那么我们不会重新启用访问。 我们假设有些事情已经被深深地打破了,不要冒着让代码变得更糟的风险。 让调用者处理这个问题,如果可以的话。

那么什么时候运行finally块是个好主意? 首先,当预期的例外。 例如,您可能会期望locking文件的尝试可能会失败,因为其他人将其locking。 在这种情况下,捕捉exception并将其报告给用户是有意义的。 在这种情况下,什么是破的不确定性会降低; 你不可能通过清理而使事情变得更糟。

其次,当你正在清理的资源是一个稀缺的系统资源。 例如,closuresfinally块中的文件句柄是有意义的。 (“使用”当然只是写一个try-finally块的另一种方式。)文件的内容可能已经损坏,但是现在你无能为力了。 文件句柄最终会被closures,所以最好不要迟到。