ekk*_*kis 4 c# exception-handling
当我们在try/catch中包含一堆语句并且其中一个发出异常时,在catch中我们无法知道哪个语句导致了异常(ex.stacktrace显示了我们当前的方法(doit))调用者,调用者的调用者等,但不是do1或do2):
function doit() {
try {
do1();
do2();
[...]
}
catch (Exception ex) {
// what failed?
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说,我已采取包装所有陈述和重新抛出,有点像:
private void do1() {
try {
// do whatever
} catch(Exception e) {
// write to my error log
throw new Exception("do1: " + e.Message, e.InnerException);
}
}
Run Code Online (Sandbox Code Playgroud)
这会在我的日志中留下痕迹,并使链条可用于上游.当然,问题是我必须用这种代码包装我写的每个方法.
有些东西告诉我,我对此很愚蠢.什么是正确的方法?
好吧,这很难做到正确,因为异常处理是一个非常敏感的主题,在过去,人们已经就如何正确行事进行了宗教战争.
首先:既不使用空的catch(try { ... } catch { ... }),也不使用catch(Exception ex).Exception派生类的唯一目的是为您提供有关发生的异常类型的丰富信息,以便您可以在异常处理程序中执行有意义的操作(如果线程崩溃重新启动它,如果数据库连接失败,则非永久性地再次尝试,然后失败等).
人们倾向于使用catch-all处理程序来处理代码的最外层部分以记录未捕获的异常,这是好的,但无论如何你应该提示用户或重新抛出异常(使用throw,不是throw ex- 有一吨关于这一点的讨论).
基本上,您没有以编程方式关心异常发生的位置.您可以处理它,也可以不处理它.如果你无法处理它,那么你就无法抓住它.
附录:最重要的原因是"如果你可以做些什么,就这样做,否则你不敢触摸那个例外"的哲学是,默默地捕获异常(无论是否记录)都会导致真正难以发现的错误.将它们推送到日志文件可能是不够的,因为在实时系统中,您可能无法获得完全注释的堆栈跟踪(带有行号和所有内容).
附录2:例如,需要整数输入的文本框.如果用户提供的字符串无法有效处理输入,则可能会抛出转换异常,捕获该特定异常并将文本框重置为其旧值,并可能通知用户错误输入.或者,您的程序可能只是因为异常而死(设计不好,您可以从该异常中恢复)或者静默继续显示错误输入,但仍然使用旧值(设计错误,程序误导).
| 归档时间: |
|
| 查看次数: |
11572 次 |
| 最近记录: |