在c#om nom nom中吃异常

Der*_*ell 10 c# exception-handling

鉴于吃异常总是糟糕的juju和重新抛出异常会丢失调用堆栈,重新考虑以下因素的正确方法是什么?

吃异常:

try
{
  … do something meaningful
}
catch(SomeException ex)
{
   // eat exception
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*ers 29

try
{
 ...
}
catch(SomeException e)
{
 //Do whatever is needed with e
 throw; //This rethrows and preserves call stack.
}
Run Code Online (Sandbox Code Playgroud)

  • 编辑得更清楚一点.基本上表明你可以捕获异常并执行异常所需的任何操作,然后在保留调用堆栈的同时重新抛出. (8认同)
  • @Richard不喜欢捕获/记录然后重新投掷,个人认为它使记录变得混乱,因为你不知道将要记录的是什么.感觉非常紧迫,并且没有定义的错误逻辑. (3认同)
  • @Aaron:它从来都不是理想的,但有一些实际的原因(除了被现有团队强制执行的预先建立的编码约定所要求).例如,如果您正在使用远程处理,并且需要在服务器上的业务逻辑中记录所有异常,同时仍然将异常传播到客户端,而不是什么也不做.然后在客户端,也可以以另一种方式处理异常,例如重试,显示错误消息等.... (3认同)
  • 如果你在扔,那么你为什么要捕捉?! (2认同)
  • 好吧,`throw;`总是不行.读我的回答. (2认同)

Tim*_*ora 7

捕获并处理特定类型的异常.良好做法是不是正好赶上System.Exception的.一个健壮的例程将强烈地键入它知道如何处理的异常.

不应将异常用于控制流,但通常需要根据异常类型采取特定的展开过程.

根据具体类型,您可能会也可能不会选择重新抛出它.例如,将ASP解析异常抛出到使用导致异常的代码的错误页面将导致无限循环.

try
{

}
catch( FileIOException )
{
    // unwind and re-throw as determined by the specific exception type
}
catch( UnauthorizedAccessException )
{
    // unwind and re-throw as determined by the specific exception type
}
catch( SomeOtherException )
{
    // unwind and re-throw as determined by the specific exception type
}
catch( Exception )
{
   // log and re-throw...add your own message, capture the call stack, etc.

   // throw original exception
   throw;

   // OR, throw your own custom exception that provides more specific detail and captures
   // the original exception as the inner exception
   throw new MyStronglyTypedException();
}
finally
{
     // always clean up
}
Run Code Online (Sandbox Code Playgroud)

  • 我想你想把Exception.StackTrace传递给MyStronglyTypedException() (2认同)

Jas*_*ams 5

大多数人认为吃/禁止异常是完全邪恶的,尤其是对于所有人而言.(具有讽刺意味的是,他们使用了所有的回应"不要使用全能,它是邪恶的":-).我不理解人们谴责这种观点的宗教热情,因为如果使用得当,这种做法没有任何问题.

  • 在我的书中,最糟糕的情况是我的程序灾难性地退出 - >这会造成一个非常不满意的客户,总数据丢失情况.每次都会出现未处理的异常.因此,如果异常被抑制,则无法处理异常在统计上比任何不稳定风险更危险.鉴于此,我们可以合理地做些什么来防止未处理的异常发生是一件好事.

  • 许多人似乎忘记了catch alls经常可以正确处理任何异常,即使他们不知道异常的细节.我的意思是他们可以保证程序状态保持稳定,程序继续在其设计参数范围内运行.或者甚至可能存在副作用,例如用户发现按钮无响应,但它们仍然不会丢失任何数据(即优雅降级比致命崩溃更好).例如,有时您希望在成功时返回一个值,如果由于任何原因失败则返回默认值.设计代码的一部分是知道何时向用户报告错误以及何时代表他们修复问题,以便他们的程序"正常工作".在这种情况下,精心设计的全能通常是工作的正确工具.

  • 例外让我担心.从根本上说,如果我不处理它,可以保证程序崩溃.如果我只为我期望的异常添加特定的异常处理,那么我的程序本身就很脆弱.考虑一下它是多么容易被打破:

    • 如果程序员忘记记录他们可能抛出的一个异常,我就不知道我需要抓住它,而且我的代码会有一个我不知道的漏洞.
    • 如果有人更新了一个方法以便它抛出一个新的异常类型,那么新的异常可能会使调用堆栈起作用,直到它碰到我的代码.但我的代码不是为处理异常而构建的.不要告诉我,我打电话的图书馆永远不会改变.
    • 您专门处理的每种异常类型都是另一个要测试的代码路径.它显着地增加了测试的复杂性和/或可能忽略处理代码的风险.
  • 支持"压制是邪恶的"观点的观点是,所有异常都代表不稳定或错误 - 但在许多情况下,程序员使用异常只返回状态信息.例如,FileNotFound.编写文件I/O代码的程序员已经代表我决定丢失文件是致命错误.它可能是.我应该抓住这个并确定它实际上是一种常见的,完全正常的或预期的情况.在很多时候,抑制异常是必要的,只需阻止别人的"决定"取出我的申请.简单地忽略错误返回码的旧方法并不总是坏事,特别是考虑到捕获和抑制无数"状态"所需的努力量

静默地吃/禁止异常的诀窍就是确保这是处理它们的正确方法.(在许多情况下,它不是).所以可能没有必要重构你的示例代码 - 它可能不是坏juju.