在 try catch 块中抛出异常

28
try { 
  if (isFileDownloaded)
   // do stuff
  else
   throw new CustomException()
} 
catch (Exception e)
{
  // something went wrong to save the error to log
}
finally
{
  //release resources
}
我的问题是,catch会捕获try块中抛出的ApplicationException吗?这种写法是否不好?是否应该用另一种方式书写?

什么是ApplicationException - mhrsalehi
4个回答

37

catch 语句会捕获你的异常(和任何其他发生的异常)。尽管如此,如果可能的话,我会尽量避免编写这样的代码。

个人而言,我认为在同一作用域中抛出异常时,几乎没有理由使用异常处理(catch)。如果您可以在方法中处理错误,请将异常处理(例如:记录日志)直接放在 try 块中。

在我的看法中,使用 catch 更有用的是捕获在 try 块内部调用的方法引发的异常。例如,如果你的 // do stuff 部分恰好调用了一个引发异常的方法,则这将更加有用。

此外,我建议不要捕获每个异常(Exception e),而是要正确处理您可以处理的特定类型的异常。唯一的例外是,如果您在 catch 中重新抛出异常-例如:将其用于记录目的,但仍然让其沿着调用堆栈冒泡。


3
else块中,可以执行在catch块中所做的任何操作来引发异常。只有在特殊情况下才应该引发异常。另外,不要习惯于将异常对象称为e,因为这会与事件处理程序中的EventArgs参数产生冲突。 - Philip Smith
@Philip:“在catch中要做的任何事情,你都可以在引发异常的else中完成。” - 这就是我的观点 :) 至于你的其他论点,我在某种程度上同意,但个人而言,我没有问题将异常对象命名为 e(尽管我通常使用更有意义的名称),因为它们很少直接与 EventArgs 一起使用。 - Reed Copsey
2
假设我有一个方法,它读取一些带有指令的XML文件。它可能会由于磁盘I/O或XML解析而引发异常,但这两种情况都被视为罕见。它还可能发现XML内容在语义上无效,这也是罕见的。考虑到我们已经有一个捕获块来记录失败的日志,那么当出现语义违规时,抛出异常有何不妥之处? - Steven Sudit
@Reed:我知道你会这样做,但我不明白为什么。 - Steven Sudit
@Philip: 我并不是说它们永远不会相遇 - 但有足够多的情况它们不会相遇,所以我个人不会把它作为一个规则。对于我来说,编译器已经很好地处理了这些情况。 - Reed Copsey
显示剩余10条评论

13

是的,它会捕获ApplicationException,因为它派生自Exception

在大多数情况下,处理基础异常应该是可以的,除非您需要记录或执行其他类型的异常操作...

try {
    if (isFileDownloaded)
       doSomeThings();
    else
       throw new ApplicationException("Something expectedly unexpected happened.");
}
catch(ApplicationException e)
{
   // log application exception here...
}
catch(Exception e)
{
   // log all other exceptions here...
}
finally
{
   // release resources...
}

2
此外,顺便说一下,自 .NET 2.0 起,ApplicationException 已被弃用作为一个异常的派生类。它从来没有被设计为一个单独抛出的异常,因此你可能根本不应该使用它。

FxCop强制执行这些规则。您不能抛出基本异常或从“ApplicationException”或“SystemException”派生。这些是基本异常,以及“Exception”本身。 - Philip Smith

1

是的,catch会捕获您的ApplicationException,但这是一种糟糕的编码风格。作为一个好的通用规则,只有捕获特定的异常和那些您要处理的异常,比如修复应用程序状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接