我见过有人说,使用不带参数的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仍然会运行。

其他回答

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

Finally是可选的——如果没有资源可以清理,就没有理由使用“Finally”块。

我同意这里的共识——空的“catch”是不好的,因为它掩盖了try块中可能发生的任何异常。

此外,从可读性的角度来看,当我看到一个“try”块时,我假设会有一个对应的“catch”语句。如果你只使用'try'来确保在'finally'块中分配资源,你可以考虑使用'using'语句:

using (StreamReader reader = new StreamReader('myfile.txt'))
{
    // do stuff here
} // reader.dispose() is called automatically

你可以对任何实现IDisposable的对象使用'using'语句。对象的dispose()方法在块的末尾被自动调用。

finally块仍然会抛出任何引发的异常。最后要做的就是确保在抛出异常之前运行清理代码。

The try..catch with an empty catch will completely consume any exception and hide the fact that it happened. The reader will be closed, but there's no telling if the correct thing happened. What if your intent was to write i to the file? In this case, you won't make it to that part of the code and myfile.txt will be empty. Do all of the downstream methods handle this properly? When you see the empty file, will you be able to correctly guess that it's empty because an exception was thrown? Better to throw the exception and let it be known that you're doing something wrong.

另一个原因是这样做的try. catch是完全错误的。你这样做的意思是,“无论发生什么,我都能处理好。”StackOverflowException呢,你能在那之后清理吗?OutOfMemoryException呢?一般来说,您应该只处理您期望并知道如何处理的异常。

添加catch子句只是为了重新抛出异常,这是一种糟糕的实践。