这有点抽象,但有没有什么可能的方法来抛出异常并让它进入多个catch块?例如,如果它匹配一个特定的异常,然后是一个非特定的异常。我可以执行多个Catch块吗?
catch(Arithmetic exception)
{
//do stuff
}
catch(Exception exception)
{
//do stuff
}
这有点抽象,但有没有什么可能的方法来抛出异常并让它进入多个catch块?例如,如果它匹配一个特定的异常,然后是一个非特定的异常。我可以执行多个Catch块吗?
catch(Arithmetic exception)
{
//do stuff
}
catch(Exception exception)
{
//do stuff
}
拥有多个不同类型的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
}
或者,您可以在基于特定类型的异常,一般异常处理程序过滤。
不可以在两个catch块中为单个异常执行代码。
我可能会重构泛型异常块中的代码为可以从任何一个被调用的东西。
try
{
// blah blah blah
{
catch(Arithmetic ae)
{
HandleArithmeticException(ae);
HandleGenericException(ae);
}
catch(Exception e)
{
HandleGenericException(e);
}
您不能有多个异常块处理相同的异常。但你可以做是赶上一般例外,然后尝试投射到更具体的,是这样的:
catch (Exception exception)
{
var aex = exception as ArithmeticException
if (aex != null)
{
// do stuff specific to this exception type
}
// then do general stuff
}
这被称为异常过滤和C#不支持(有人告诉我它可能在VB.NET中)。
一个解决方法是捕获一般异常,然后检查catch块中的异常类型,并在继续执行块的其余部分之前对其执行任何特定处理。
像其他人一样,这个异常将被最具体的catch块捕获。
虽然有异常处理,但却带来了我的沮丧。我希望你能这样做
catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex)
{
}
而不必做
catch (ArgumentNullExcpetion e)
{
}
catch (ArugmentOutOfRangeException outOfRange)
{
}
我明白这对你可能是不同的异常做不同的事情,但有时我想结合他们的推理。
这两个都不是来自ArgumentException - 如果你真的想为两者做同样的事情,只需要捕获ArgumentException。如果你只想捕获子异常,那么你需要使用条件逻辑过滤(并重新抛出)ArgumentException。你的一般观点是好的,但这不是最好的例子。也许像ValidationException(模型错误)和SqlException(违反约束)类似的地方它们不在同一个层次结构中是一个更好的例子。 – tvanfosson 2010-10-27 16:49:31
当你说“异常将被最具体的catch块捕获”时,我不认为你的100%正确。这也取决于顺序。所以,如果你有一个所有的东西,所有东西都将永远属于那个,即使你有更具体的东西 – jon 2010-10-27 16:51:01
tvanfosson。接得好。我刚刚做了这个例子。你是对的,我可以在这种情况下赶上一般的父母异常。但是,是的,我想要一种方法来捕获一个catch块中的多个非相关的异常类型 – 2010-10-27 18:09:25
如果您使用的是VB.NET,可以将Arithmetic异常中的错误处理程序抽象为函数或方法调用,该函数或方法调用始终返回false。
然后,你可以写这样的:
Catch ex as Arithmetic When HandleArithmetic()
Catch ex as Exception
End Try
不,我会主张这种用法,虽然我已经看到它之前,建议进行日志记录。我不相信有一个C#等价物。
对于简单的一级层次结构,嵌套工作正常,但如果共享代码需要运行几个不同的异常情况,则可能会匆忙地变丑。这并不意味着与方法不一致,而是一种观察并不总是合适的。 – tvanfosson 2010-10-27 16:42:58
@tvanfosson:是的,这就是为什么我还添加了过滤选项。你的选择也很好。 – 2010-10-27 16:47:07