.NET和C#例外。什么是合理的捕捉
免责声明,我来自Java背景。我做的不多。这两个世界之间存在着大量的转移,但当然也存在着差异,其中之一就是人们对例外的看法 我最近回答了一个C#问题,建议在某些情况下这样做是合理的:.NET和C#例外。什么是合理的捕捉,c#,exception-handling,C#,Exception Handling,免责声明,我来自Java背景。我做的不多。这两个世界之间存在着大量的转移,但当然也存在着差异,其中之一就是人们对例外的看法 我最近回答了一个C#问题,建议在某些情况下这样做是合理的: try { some work } catch (Exeption e) { commonExceptionHandler(); } (原因并不重要)。我得到了一个我不太明白的回答: 在.NET4.0之前,很难赶上 例外。这意味着你能抓住各种各样的机会 低级致命错误等伪装 漏洞。这也意味
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
(原因并不重要)。我得到了一个我不太明白的回答:
在.NET4.0之前,很难赶上
例外。这意味着你能抓住各种各样的机会
低级致命错误等伪装
漏洞。这也意味着
某种腐败
触发这样一个异常,任何打开的
最后,堆栈上的块将被删除
执行,所以即使
callExceptionReporter函数尝试
要登录并退出,它甚至可能无法
到那一点(最后的块可能
再扔一次,或者造成更多的腐败,
或者从列表中删除一些重要的内容
磁盘或数据库)
也许我比我意识到的更困惑,但我不同意其中的一些观点。请其他人发表评论
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
在我的代码中,我调用lowLevel()
无论我是否捕获异常,这对finally块的执行都没有任何影响。当我们离开lowLevelMethod()时,finally已经运行了。如果finally要做任何不好的事情,比如损坏我的磁盘,那么它就会这样做。我抓住了这个例外没有什么区别。如果它到达我的异常块,我需要做正确的事情,但我不能成为dmis最终执行的原因,我认为引用的响应是错误的(或者可能是指2.0而不是4.0)?对我来说这听起来有点假。关于你的第三个问题: 如果你有
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
我认为您所问的回答只是意味着一些低级方法可能会使用异常来通知某些外部方法必须特别小心。如果您在catch-all处理程序中忘记了这些异常,并且不重新引用它们,则可能会出现问题
通常,我更喜欢仔细考虑哪些异常可能被抛出,并明确地捕获它们。我仅在生产环境的最外层使用“通用处理程序”,以便记录意外异常,并以格式良好的方式将其呈现给客户(包括向我们发送日志文件的提示)。作为一般规则,您不应捕获异常,除非:
最终
块始终执行。您的代码示例是正确的-低级方法应该只有try
和finally
。例如,非托管调用可能知道它需要处理非托管资源,但这不会暴露给调用它的.Net方法。该调用应该在其finally
块中除去非托管资源,调用托管方法可以处理异常,也可以将异常传递给其他方法
如果异常中存在需要处理的内容,则应重新抛出该异常,例如:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
我的座右铭是处理您可以(或需要)的事情,让任何其他异常冒泡并在未处理的异常事件中捕获它们 您是正确的,在退出该方法之前,始终会调用finally块(即使在try部分引发异常的情况下也是如此)。因此,您是否希望捕获out方法上的异常完全取决于您……这不应影响正在调用的finally块。对于问题#2: 作者的意思是“腐败状态例外”。它们将在.NET4.0中引入(CLR团队在PDC2008的谈话中宣布了这一点) 正常捕获块无法捕获损坏的状态异常。示例:访问冲突、内存无效。 但您可能希望捕获以下异常:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}