比多个捕获块更优雅的异常处理?

Aar*_*ron 47 .net c# error-handling exception

使用C#,是否有更好的方法来处理多种类型的异常,而不是一堆丑陋的catch块?

什么是这种情况的最佳做法?

例如:

try
{
    // Many types of exceptions can be thrown
}
catch (CustomException ce)
{
    ...
}
catch (AnotherCustomException ace)
{
    ...
}
catch (Exception ex)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 71

在我看来,一堆"丑陋"的捕获块是处理这种情况的最佳方式.

我更喜欢这个的原因是它非常明确.您明确说明了要处理的异常以及应如何处理这些异常.在大多数情况下,尝试将处理合并为更简洁形式的其他形式会失去可读性.

我的建议是坚持这一点,并处理你希望明确处理的异常,每个异常都在他们自己的catch块中.


DOK*_*DOK 21

我同意里德:这是最好的方法.

我会添加这些评论:

只抓住你要做的事情.如果您无法解决问题,那么捕获特定异常就没有意义了.

不要过度使用catch块.在许多无法解决异常的情况下,最好让异常气泡到达中心点(例如Page_Error)并在那里捕获它.然后,您记录该异常并向用户显示一条消息.

  • +1 - 关于不捕捉"额外"例外的好点.我试图提到这一点(在我的说法中,它会让你明确表达你想要处理的事情) - 但你是对的 - 你通常不应该处理所有事情,除非你打算用有意义的方式处理它办法. (6认同)

Mar*_*ett 15

关于您可以做的唯一其他事情是模拟VB.NET的异常过滤器:

try {
    DoSomething();
} catch (Exception e) {
    if (!ex is CustomException && !ex is AnotherCustomException) {
       throw;
    }
    // handle
}
Run Code Online (Sandbox Code Playgroud)

有时这更好,有时不是.如果在处理程序中有一些我想要的通用逻辑,我主要使用它,但异常不共享基类型.

  • 这仍然是负面的逻辑,你刚刚在它上面运行了De Morgan.可读性无论如何都可能是坏的.我会做类似`if(ex是CustomException || ex是AnotherCustomException){/*handle*/} else {throw; }`或`bool canHandle = ex是CustomException || ex是AnotherCustomException; 如果(!canHandle)扔;/*handle*/` (3认同)
  • 消极的逻辑让我的左眼觉得好笑.在这样的情况下,`if(!(ex是CustomException || ex是AnotherCustomException))怎么样? (2认同)

Ken*_*art 10

不幸的是,C#没有像VB.NET这样的用户异常过滤器,所以你只限于:

  1. 捕捉所有异常的共同祖先.这可能是您想要的,也可能不是您想要的,因为您可能不希望捕获其他后代异常类型.
  2. 将异常处理逻辑移动到另一个方法并从每个处理程序调用它.
  3. 为每个处理程序重复异常逻辑.
  4. 将异常处理逻辑移动到支持过滤器的语言,例如VB.NET.

  • 从C#6.0语言规范(.NET 4.6/Visual Studio 2015中的新增功能)开始,C#使用以下语法支持"异常过滤器":`catch(Exception ex)if(ex.Message.Contains("Fatal"))`. (5认同)

小智 5

如果你需要编写一个非常大的代码,我会建议检查一些AOP框架.我个人使用PostSharp.然后,您可以将所有异常处理代码隐藏到方面中.