我见过有人说,使用不带参数的catch是一种糟糕的形式,尤其是当catch什么都不做的时候:

StreamReader reader=new  StreamReader("myfile.txt");
try
{
  int i = 5 / 0;
}
catch   // No args, so it will catch any exception
{}
reader.Close();

然而,这被认为是良好的形式:

StreamReader reader=new  StreamReader("myfile.txt");
try
{
  int i = 5 / 0;
}
finally   // Will execute despite any exception
{
  reader.Close();
}

据我所知,将清理代码放在finally块和将清理代码放在try. catch块之后的唯一区别是,如果你在try块中有返回语句(在这种情况下,finally中的清理代码将运行,但try. catch块之后的代码将不会运行)。

否则,最后有什么特别的?


当前回答

可能有很多原因,其中之一就是异常执行非常慢。如果这种情况经常发生,很容易缩短执行时间。

其他回答

使用finally,您可以清理资源,即使您的catch语句将异常抛出给调用程序。与包含空catch语句的示例相比,差别不大。但是,如果在catch中执行了一些处理并抛出错误,或者甚至根本没有catch, finally仍然会运行。

最后无论如何都会执行。如果你的try块成功,它就会执行,如果你的try块失败,它就会执行catch块,然后是finally块。

此外,最好尝试使用以下结构:

using (StreamReader reader=new  StreamReader("myfile.txt"))
{
}

由于using语句被自动包装在try / finally语句中,流将自动关闭。(如果想要真正捕获异常,则需要在using语句周围加上try / catch)。

“Finally”是一个声明,“你必须总是做一些事情来确保程序状态正常”。因此,如果存在异常可能会抛出程序状态,那么拥有一个异常总是很好的形式。编译器还会竭尽全力确保Finally代码运行。

“Catch”是“我可以从这个异常中恢复”的声明。您应该只从真正可以纠正的异常中恢复—不带参数的catch表示“嘿,我可以从任何异常中恢复!”,这几乎总是不正确的。

如果有可能从每个异常中恢复,那么它就真的是语义上的吹毛求疵,关于你所声明的意图是什么。然而,事实并非如此,而且几乎可以肯定的是,在你上面的框架能够更好地处理某些异常。因此,使用finally,让您的清理代码免费运行,但仍然让更有知识的处理程序来处理问题。

首先,捕获您懒得处理的异常是一种糟糕的实践。请参阅《改进。net应用程序性能和可伸缩性》中关于. net性能的第5章。旁注,您可能应该在try块中加载流,这样,如果它失败,您就可以捕获相关异常。在try块之外创建流会破坏它的目的。

使用Try…Catch . .最后,如果您的方法知道如何在本地处理异常。异常发生在Try中,在Catch中处理,然后在Finally中完成清理。

如果你的方法不知道如何处理异常,但需要在异常发生后进行清理,请使用Try..最后

通过这种方式,异常被传播到调用方法,如果调用方法中有任何合适的Catch语句,则进行处理。如果当前方法或任何调用方法中没有异常处理程序,则应用程序将崩溃。

最后,确保在将异常传播到调用方法之前完成了本地清理。