2010-10-27 116 views
17

这有点抽象,但有没有什么可能的方法来抛出异常并让它进入多个catch块?例如,如果它匹配一个特定的异常,然后是一个非特定的异常。我可以执行多个Catch块吗?

catch(Arithmetic exception) 
{ 
    //do stuff 
} 
catch(Exception exception) 
{ 
    //do stuff 
} 

回答

30

拥有多个不同类型的catch块是完全可以接受的。但是,行为是第一个候选块处理异常。

它不会进入两个catch块。与异常类型相匹配的第一个catch块将处理该特定异常,并且不会处理其他异常,即使它在处理程序中被重新抛出。一旦异常进入catch块,任何后续的将被跳过。

为了有陷入两个区块异常,你将需要要么窝块,像这样:

try 
{ 
    try 
    { 
     // Do something that throws ArithmeticException 
    } 
    catch(ArithmeticException arithException) 
    { 
     // This handles the thrown exception.... 

     throw; // Rethrow so the outer handler sees it too 
    } 
} 
catch (Exception e) 
{ 
    // This gets hit as well, now, since the "inner" block rethrew the exception 
} 

或者,您可以在基于特定类型的异常,一般异常处理程序过滤。

+2

对于简单的一级层次结构,嵌套工作正常,但如果共享代码需要运行几个不同的异常情况,则可能会匆忙地变丑。这并不意味着与方法不一致,而是一种观察并不总是合适的。 – tvanfosson 2010-10-27 16:42:58

+0

@tvanfosson:是的,这就是为什么我还添加了过滤选项。你的选择也很好。 – 2010-10-27 16:47:07

18

不可以在两个catch块中为单个异常执行代码。

我可能会重构泛型异常块中的代码为可以从任何一个被调用的东西。

try 
{ 
    // blah blah blah 
{ 
catch(Arithmetic ae) 
{ 
    HandleArithmeticException(ae); 
    HandleGenericException(ae); 
} 
catch(Exception e) 
{ 
    HandleGenericException(e); 
} 
1

您不能有多个异常块处理相同的异常。但你可以是赶上一般例外,然后尝试投射到更具体的,是这样的:

catch (Exception exception) 
{ 
    var aex = exception as ArithmeticException 
    if (aex != null) 
    { 
     // do stuff specific to this exception type 
    } 
    // then do general stuff 
} 
0

这被称为异常过滤和C#不支持(有人告诉我它可能在VB.NET中)。

一个解决方法是捕获一般异常,然后检查catch块中的异常类型,并在继续执行块的其余部分之前对其执行任何特定处理。

1

像其他人一样,这个异常将被最具体的catch块捕获。

虽然有异常处理,但却带来了我的沮丧。我希望你能这样做

catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex) 
{ 

} 

而不必做

catch (ArgumentNullExcpetion e) 
{ 
} 
catch (ArugmentOutOfRangeException outOfRange) 
{ 
} 

我明白这对你可能是不同的异常做不同的事情,但有时我想结合他们的推理。

+1

这两个都不是来自ArgumentException - 如果你真的想为两者做同样的事情,只需要捕获ArgumentException。如果你只想捕获子异常,那么你需要使用条件逻辑过滤(并重新抛出)ArgumentException。你的一般观点是好的,但这不是最好的例子。也许像ValidationException(模型错误)和SqlException(违反约束)类似的地方它们不在同一个层次结构中是一个更好的例子。 – tvanfosson 2010-10-27 16:49:31

+1

当你说“异常将被最具体的catch块捕获”时,我不认为你的100%正确。这也取决于顺序。所以,如果你有一个所有的东西,所有东西都将永远属于那个,即使你有更具体的东西 – jon 2010-10-27 16:51:01

+0

tvanfosson。接得好。我刚刚做了这个例子。你是对的,我可以在这种情况下赶上一般的父母异常。但是,是的,我想要一种方法来捕获一个catch块中的多个非相关的异常类型 – 2010-10-27 18:09:25

2

如果您使用的是VB.NET,可以将Arithmetic异常中的错误处理程序抽象为函数或方法调用,该函数或方法调用始终返回false。

然后,你可以写这样的:

Catch ex as Arithmetic When HandleArithmetic() 
Catch ex as Exception 

End Try 

不,我会主张这种用法,虽然我已经看到它之前,建议进行日志记录。我不相信有一个C#等价物。

相关问题