3

C#中异常处理的范围是什么。我目前正在审查我团队中另一位程序员的一些代码,他的功能布局有点像这样:

private void function1() {
try {
function2();
}
catch (Exception ex) {
EmailException(ex.message());
}}

private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
}}

大部分处理代码在function2中。但是他的报告处理在function1中。function2 中的异常会返回到发送报告的 function1 处理程序吗?

编辑: 感谢您的回复,他们都非常有帮助!

4

5 回答 5

4

假设// Handle it here不重新抛出异常,function1将永远不会看到原始异常。

不过,它可能function2会引发一个问题catch,就像它可能EmailException会在function1.

于 2012-06-06T15:44:02.920 回答
4

除非

a)function2重新抛出原始异常throw或新异常throw new ...

b) 在 的 catch 块内或之后发生意外异常function2(在这种情况下实际上是不可能的,因为该catch块是在 中发生的最后一件事function2)。

于 2012-06-06T15:44:12.043 回答
2

不,异常只会在被捕获之前传播。

catch但是,您可以在in末尾重新抛出异常function2,从而导致所需的行为:

private void function2() {
    try {
        // Do stuff
    }
    catch (Exception ex) {
        // Handle it here
        throw;    // <- Re-throw the exception.
                  // Note this is different from `throw ex;`
    }
}
于 2012-06-06T15:43:48.577 回答
2

function2 中的异常会返回到发送报告的 function1 处理程序吗?

没有,除非

  • 在 function2 的 try 块之外发生异常
  • 在function2异常块内发生异常
  • 抛出异常,例如trowtrow ex从 function2 的异常块
  • 在 function2 的 try 块中引发了一个异常,该异常会自动追溯,如ThreadAbortException
于 2012-06-06T15:44:27.407 回答
1

在.net中,当异常发生时,系统会搜索try堆栈中的嵌套块,以确定是否有catch可以捕获异常的块。这发生在任何finally块运行之前。如果没有任何块可以捕获异常,系统将调用“未处理的异常”处理程序而不运行任何finally块。

如果系统确实确定有一个可以捕获异常的块,它将开始展开堆栈并运行finally与内部块关联的try块,直到它已经将堆栈一直展开到catch它找到的块,或者异常发生在执行finally块时抛出。在后一种情况下,前面的异常将被放弃,不再进一步处理;异常处理将从新抛出的异常重新开始。

尽管想要捕获异常与仅仅想要对其采取行动(但让它被视为未捕获)之间存在语义差异,但在 C# 中没有明确的方式来表达这种区别。捕获异常的代码有望解决它。在 C# 中可以做的最好的事情是使用 a catch(表示系统的异常处理逻辑认为有人会捕获异常),然后使用 a throw,表示毕竟不想解决它(这会发生在内部“终于”块运行后)。在其他一些语言(例如 vb.net)中,可以在finally块运行之前对异常采取行动,而无需捕获它们。虽然没有大量的情况是 acatchthrow与在没有 ing 的情况下捕获异常不同catch,很少有区别很重要的情况。如果一个人正在使用 C# 并且希望避免对可能希望在终结器块运行之前从内部代码中捕获异常的周围代码产生敌意,那么最好的方法可能是编写一个用 vb 编写的异常处理包装器方法(或者让其他人做它),将其编译为 DLL,然后使用 lambdas 提供这样的函数方法,以便它在合适的 try/filter/catch/finally 块中调用。

于 2012-06-06T17:26:14.487 回答