在同一个Catch块中捕获两个异常
本文关键字:两个 异常 Catch 同一个 | 更新日期: 2023-09-27 17:49:26
我有一个方法,可以抛出两个不同的异常,CommuncationException
和SystemException
。在这两种情况下,我都使用了相同的三行代码块。
try {
...
}
catch (CommunicationException ce) {
...
}
catch {SystemExcetion se) {
...
}
有可能那样做吗?
try {
...
}
catch (CommunicationException ce, SystemException se) {
...
}
那么我就不用写这么多代码了。我知道我可以将异常处理提取到一个私有方法,但由于代码只有3行长,方法定义将比主体本身占用更多的代码。
如果你可以升级你的应用程序到c# 6,你是幸运的。新的c#版本实现了Exception过滤器。所以你可以这样写:
catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
//handle it
}
有些人认为这段代码和
是一样的catch (Exception ex) {
if (ex is CommunicationException || ex is SystemException) {
//handle it
}
throw;
}
但它不是。实际上,这是c# 6中唯一一个在以前的版本中无法模拟的新特性。首先,重掷意味着比跳过接球更大的开销。其次,它在语义上不等同。在调试代码时,新特性保留了堆栈的完整性。如果没有这个特性,崩溃转储就不那么有用,甚至毫无用处。
查看CodePlex上关于这个的讨论。还有一个例子来说明它们的区别
事实上,您只能捕获SystemException
,它也可以处理CommunicationException
,因为CommunicationException
派生自SystemException
catch (SystemException se) {
... //this handles both exceptions
}
不幸的是,没有办法。您使用的语法是无效的,并且不可能像在switch语句中那样失败。我认为你应该使用private方法。
一个简单的变通方法是这样的:
var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
// code that throws
}
catch(CommuncationException ex)
{
exceptionHandler(ex);
}
catch(SystemException ex)
{
exceptionHandler(ex);
}
你需要自己决定这是否有意义
不行,你不能那样做。我知道的唯一方法是捕获一个泛型异常,然后检查它是什么类型:
try
{
...
}
catch(Exception ex)
{
if(ex is CommunicationException || ex is SystemException)
{
...
}
else
{
... // throw; if you don't want to handle it
}
}
try {
...
}
catch (CommunicationException ce) {
HandleMyError(ce);
}
catch {SystemExcetion se) {
HandleMyError(se);
}
private void HandleMyError(Exception ex)
{
// handle your error
}
可能的副本
一次捕获多个异常?
我在这里引用答案:
catch (Exception ex)
{
if (ex is FormatException ||
ex is OverflowException)
{
WebId = Guid.Empty;
return;
}
else
{
throw;
}
}
把这个从历史的深处拖上来,因为它碰巧出现在一些搜索结果中。
随着c# 7.0的出现(它在2017年与VS2017、。net框架4.7和。net core 2.0一起出现),你现在可以做这样的事情:
try {
...
}
catch (Exception e) when (e is CommunicationException || e is SystemException) {
...
}
由于您对两种类型的异常都做了相同的处理,因此您可以这样做:
try
{
//do stuff
}
catch(Exception ex)
{
//normal exception handling here
}
只有当你需要为它做一些独特的事情时才捕捉显式异常类型