一次捕获多个异常?
时间: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 }