当前位置:  开发笔记 > 编程语言 > 正文

为什么尝试{...}最终{...}好; 试试{}}抓住{}不好?

如何解决《为什么尝试{}最终{}好;试试{}}抓住{}不好?》经验,为你挑选了6个好方法。

我见过有人说使用不带参数的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块中有return语句(在这种情况下,最后清理代码将是运行,但try..catch之后的代码不会).

否则,最后有什么特别之处?



1> Khoth..:

最大的区别在于try...catch会吞下异常,隐藏发生错误的事实.try..finally将运行您的清理代码然后异常将继续,由知道如何处理它的东西处理.


大卫 - 我更喜欢程序快速失败,所以我可以意识到问题,而不是让程序运行在一个未知的状态.
@DavidArno,任何用封装编写的代码都应该只处理其范围内的异常.应该传递任何其他东西供其他人处理.如果我有一个从用户那里获取文件名的应用程序然后读取该文件,并且我的文件阅读器获得打开文件的异常,它应该将它们传递(或者使用异常并抛出一个新的)以便应用程序可以说,嘿 - 文件没有打开,让我们提示用户另一个.文件阅读器不应该提示用户或采取任何其他操作作为响应.它的唯一目的是读取文件.
任何用封装编写的代码都可能只能在引发异常时处理异常.简单地将它传递回调用堆栈,绝望地希望其他东西能够处理一些任意异常,这是灾难的一个秘诀.
如果你的程序在异常后处于未知状态,那么你的代码就错了.
在大多数情况下,更明显的是为什么从应用程序级别(例如,某个配置设置)发生特定异常而不是类librray级别.
您忘记了未经检查的异常.几乎任何方法都可以抛出OutOfMemoryError或类似的东西.你希望你的finally块在退出之前至少尝试清理.

2> Adam Wright..:

"最后"是一个声明"你必须做的事情,以确保程序状态是理智的".因此,如果异常可能会导致程序状态失效,那么拥有一个总是很好的形式.编译器还竭尽全力确保运行您的Finally代码.

"Catch"是"我可以从此异常中恢复"的声明.你应该只从你真正可以纠正的异常中恢复过来 - 没有争论就说:"嘿,我可以从任何东西中恢复过来!",这几乎总是不真实的.

如果有可能从每个例外中恢复,那么它实际上是一个语义狡辩,关于你宣布你的意图是什么.但是,它不是,而且几乎可以肯定,高于你的帧将更好地处理某些异常.因此,最后使用,让你的清理代码免费运行,但仍然让更多知识渊博的处理程序处理这个问题.



3> chakrit..:

因为当一行引发异常时,你就不会知道它.

使用第一个代码块,将简单地吸收异常,即使程序状态可能出错,程序也将继续执行.

与第二块,异常会被抛出,并冒泡,但reader.Close()仍然保证运行.

如果不期望异常,那么不要放一个try..catch块,以后当程序进入错误状态并且你不知道为什么时很难调试.



4> Mark Ingram..:

最后无论如何执行.因此,如果你的try块成功,它将执行,如果你的try块失败,它将执行catch块,然后执行finally块.

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

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

由于using语句自动包装在try/finally中,因此流将自动关闭.(如果要实际捕获异常,则需要在using语句周围放置一个try/catch).


这是不正确的.使用不用try/catch包装代码,应该说try/finally

5> Robert Pauls..:

虽然以下2个代码块是等效的,但它们并不相同.

try
{
  int i = 1/0; 
}
catch
{
  reader.Close();
  throw;
}

try
{
  int i = 1/0;
}
finally
{
  reader.Close();
}

    'finally'是意图揭示代码.您向编译器和其他程序员声明无论如何都需要运行此代码.

    如果你有多个catch块并且你有清理代码,那么你最终需要.最后,你将在每个catch块中复制清理代码.(DRY原则)

最后块是特殊的.CLR使用finally块分别识别和处理带有finally块的代码,并且CLR竭尽全力保证finally块始终执行.这不仅仅是编译器的语法糖.



6> Chris Lawlor..:

我同意这里似乎达成的共识 - 空的'catch'是坏的,因为它掩盖了try块中可能发生的任何异常.

另外,从可读性的角度来看,当我看到'try'块时,我假设会有一个相应的'catch'语句.如果您只是使用'try'以确保在'finally'块中取消分配资源,您可以考虑使用'using'语句:

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

您可以将'using'语句与任何实现IDisposable的对象一起使用.对象的dispose()方法在块结束时自动调用.

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有