比多个 Catch 块更优雅的异常处理? [复制]
Posted
技术标签:
【中文标题】比多个 Catch 块更优雅的异常处理? [复制]【英文标题】:More Elegant Exception Handling Than Multiple Catch Blocks? [duplicate] 【发布时间】:2010-10-21 22:34:57 【问题描述】:使用 C#,有没有更好的方法来处理多种类型的异常,而不是一堆丑陋的 catch 块?
这种情况的最佳做法是什么?
例如:
try
// Many types of exceptions can be thrown
catch (CustomException ce)
...
catch (AnotherCustomException ace)
...
catch (Exception ex)
...
【问题讨论】:
【参考方案1】:如果您需要编写大量这样的代码,我建议您检查一些AOP 框架。我个人使用PostSharp。 然后您可以将所有异常处理代码隐藏到方面。
【讨论】:
【参考方案2】:只抓住你需要专门解决的问题,然后离开
catch(Exception e)
对于其他所有内容(或跳过它并将此异常提供给堆栈)
【讨论】:
这不会吞下整个异常,这几乎总是一个坏主意吗? 是的,这是一段 AWFUL 代码,原样。我认为 Mash 是在暗示你扔进去……要么是那个,要么是他喝醉了。【参考方案3】:不幸的是,C# does not have user exception filters 喜欢 VB.NET,所以你只能:
-
捕获所有异常的共同祖先。这可能是也可能不是您想要的,因为您可能不想捕获其他后代异常类型。
将异常处理逻辑移动到另一个方法中并从每个处理程序中调用该方法。
为每个处理程序重复异常逻辑。
将异常处理逻辑转移到支持过滤器的语言中,例如 VB.NET。
【讨论】:
从 C# 6.0 语言规范(.NET 4.6 / Visual Studio 2015 中的新功能)开始,C# 使用以下语法支持“异常过滤器”:catch (Exception ex) if (ex.Message.Contains("Fatal"))
。【参考方案4】:
这样不好吗?
如果你只想处理一个异常:
try
// Many types of exceptions can be thrown
catch (TheExceptionIWantToHandle ex)
// handle it
catch (Exception ex)
// suppress all other exceptions
如果你想处理除一个以外的所有异常:
try
// Many types of exceptions can be thrown
catch (TheExceptionIDoNotWantToHandle ex)
// suppress all other exceptions
catch (Exception ex)
// handle it
好不好?
【讨论】:
一般来说不好。不要在不以某种方式记录异常的情况下抑制异常。否则,您可能会隐藏重要信息。此外,恕我直言,没有什么理由去做“catch (exception ex)”,除非你要记录它,或者包装它,然后使用“throw;”。声明以允许它传播。【参考方案5】:你唯一能做的就是模拟 VB.NET 的异常过滤器:
try
DoSomething();
catch (Exception e)
if (!ex is CustomException && !ex is AnotherCustomException)
throw;
// handle
有时这更好,有时则不然。如果处理程序中有一些我想要的通用逻辑,我主要会使用它,但异常不共享基本类型。
【讨论】:
负逻辑让我的左眼觉得好笑。在这种情况下,if(!(ex is CustomException || ex is AnotherCustomException))
怎么样?
这仍然是负面逻辑,您只是在上面运行了 De Morgan。无论哪种方式,可读性都可以说是糟糕的。我会做类似if (ex is CustomException || ex is AnotherCustomException) /*handle*/ else throw;
或bool canHandle = ex is CustomException || ex is AnotherCustomException; if (!canHandle) throw; /* handle */
【参考方案6】:
您应该查看企业库Exception Handling block。它允许通过策略(包装策略、传播策略、替换策略、日志记录策略等)对异常进行更精细的控制。您可以使用它来标准化编写异常块的方式并使用配置来精确处理发生的情况一种特殊类型的异常。
【讨论】:
【参考方案7】:我同意 Reed:这是最好的方法。
我会添加这些 cmets:
只捕捉你将要做的事情。如果您无法解决问题,那么捕获特定异常是没有意义的。
不要过度使用 catch 块。在许多无法解决异常的情况下,最好让异常冒泡到一个中心点(例如 Page_Error)并在那里捕获它。然后,您记录异常并向用户显示一条消息。
【讨论】:
+1 - 关于不捕获“额外”异常的要点。我试图提到这一点(在我的说法中,它使您明确说明您要处理的内容)-但您是对的-您通常不应该处理所有事情,除非您要以有意义的方式处理它方式。 也 +1。我想补充一点,有时开发人员会在每个方法中添加 catch 块,以便他们可以跟踪实际引发异常的方法。这就是堆栈跟踪的用途!【参考方案8】:在我看来,一堆“丑陋”的 catch 块是处理这种情况的最佳方法。
我喜欢这个的原因是它非常明确。您明确说明要处理哪些异常以及应如何处理它们。在大多数情况下,尝试将处理合并为更简洁的形式的其他形式会失去可读性。
我的建议是坚持这一点,并处理您希望明确处理的异常,每个异常都在它们自己的 catch 块中。
【讨论】:
您认为 Mark Brackett 的过滤器解决方案有什么缺点吗? @TrueWill:IMO,它只是降低了可维护性,并没有真正增加很多功能。话虽如此,这并不可怕 - 只是不明显。以上是关于比多个 Catch 块更优雅的异常处理? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
还在滥用try-catch处理异常?看看springboot的优雅实现吧
Java 写try...catch语句 写多个不同类型的异常捕捉好还是只写一个Exception好?