一次捕获多个异常?
时间:2020-03-06 14:44:57 来源:igfitidea点击:
不建议仅捕获System.Exception。相反,仅应捕获"已知"异常。
现在,这有时会导致不必要的重复代码,例如:
try
{
WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
WebId = Guid.Empty;
}
catch (OverflowException)
{
WebId = Guid.Empty;
}
我想知道:有没有一种方法可以捕获两个异常,并且只调用一次" WebId = Guid.Empty"调用?
给定的示例非常简单,因为它只是一个" GUID"。但是,请想象一下代码中多次修改对象的情况,如果其中一种操作以预期的方式失败,则我们想"重置""对象"。但是,如果有意外的例外,我仍然想将其提高。
解决方案
请注意,我确实找到了一种方法来执行此操作,但这看起来更像是The Daily WTF的资料:
catch (Exception ex)
{
switch (ex.GetType().Name)
{
case "System.FormatException":
case "System.OverflowException":
WebId = Guid.Empty;
break;
default:
throw;
}
}
怎么样
try
{
WebId = Guid.Empty;
WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
}
catch (OverflowException)
{
}
捕获System.Exception并打开类型
catch (Exception ex)
{
if (ex is FormatException || ex is OverflowException)
{
WebId = Guid.Empty;
return;
}
throw;
}
@米歇尔
代码略有修改:
catch (Exception ex)
{
Type exType = ex.GetType();
if (exType == typeof(System.FormatException) ||
exType == typeof(System.OverflowException)
{
WebId = Guid.Empty;
} else {
throw;
}
}
字符串比较丑陋且缓慢。
不幸的是,因为我们需要使用异常过滤器来执行此操作,因此C不会公开MSIL的功能。 VB.NET确实具有此功能,例如
Catch ex As Exception When TypeOf ex Is FormatException OrElse TypeOf ex Is OverflowException
我们可以做的是使用匿名函数封装错误代码,然后在这些特定的catch块中调用它:
Action onError = () => WebId = Guid.Empty;
try
{
// something
}
catch (FormatException)
{
onError();
}
catch (OverflowException)
{
onError();
}
catch (Exception ex)
{
if (!(
ex is FormatException ||
ex is OverflowException))
{
throw;
}
Console.WriteLine("Hello");
}
可接受的答案似乎是可以接受的,除了CodeAnalysis / FxCop会抱怨它正在捕获一般异常类型这一事实。
另外,似乎" is"运算符可能会稍微降低性能。
CA1800:不必进行不必要的强制转换,而是"考虑测试'as'运算符的结果",但是,如果这样做的话,与单独捕获每个异常的情况相比,我们将编写更多的代码。
无论如何,这是我会做的:
bool exThrown = false;
try
{
// Something
}
catch (FormatException) {
exThrown = true;
}
catch (OverflowException) {
exThrown = true;
}
if (exThrown)
{
// Something else
}

