关于C#:比多个catch块更优雅的异常处理?

More Elegant Exception Handling Than Multiple Catch Blocks?

本问题已经有最佳答案,请猛点这里访问。

使用C**,有没有更好的方法来处理多种类型的异常,而不是一堆难看的catch块?

对于这种情况,什么是最佳实践?

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try
{
    // Many types of exceptions can be thrown
}
catch (CustomException ce)
{
    ...
}
catch (AnotherCustomException ace)
{
    ...
}
catch (Exception ex)
{
    ...
}

在我看来,一堆"丑陋"的拦网是处理这种情况的最好方法。

我之所以喜欢这样,是因为它非常明确。您要明确地说明要处理哪些异常,以及应该如何处理它们。在大多数情况下,试图将处理合并为更简洁的表单的其他表单会失去可读性。

我的建议是坚持这一点,并处理希望显式处理的异常,每个异常都在各自的catch块中。


我同意里德的观点:这是最好的方法。

我将添加以下评论:

抓住你要做的事情。如果你不能解决这个问题,捕捉一个特定的异常是没有意义的。

不要过度使用catch块。在许多情况下,如果您无法解决异常,最好让异常冒泡到一个中心点(如page_错误)并在那里捕获它。然后,记录异常并向用户显示消息。


你唯一能做的就是模拟vb.net的异常过滤器:

1
2
3
4
5
6
7
8
try {
    DoSomething();
} catch (Exception e) {
    if (!ex is CustomException && !ex is AnotherCustomException) {
       throw;
    }
    // handle
}

有时这样更好,有时不行。我主要是在处理程序中需要一些公共逻辑时使用它,但是异常不共享基类型。


不幸的是,C没有像vb.net这样的用户异常过滤器,因此您只能:

  • 捕获所有异常的共同祖先。这可能是您想要的,也可能不是,因为您可能不想捕获其他后代异常类型。
  • 将异常处理逻辑移动到另一个方法中,并从每个处理程序调用该方法。
  • 为每个处理程序重复异常逻辑。
  • 将异常处理逻辑移动到支持过滤器的语言中,例如vb.net。

  • 如果您需要编写大量这样的代码,我建议您检查一些AOP框架。我个人用的是竖琴。然后可以将所有异常处理代码隐藏到方面中。


    您应该检查企业库异常处理块。它允许通过策略(包装策略、传播策略、替换策略、日志记录策略等)对异常进行更精细的粒度控制。您可以使用它来标准化编写异常块的方式,并使用配置来精确处理特定类型的异常所发生的情况。


    这样不好吗?

    如果只想处理一个异常:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    try
    {
        // Many types of exceptions can be thrown
    }
    catch (TheExceptionIWantToHandle ex)
    {
        // handle it
    }
    catch (Exception ex)
    {
        // suppress all other exceptions
    }

    如果要处理除一个例外之外的所有例外:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    try
    {
        // Many types of exceptions can be thrown
    }
    catch (TheExceptionIDoNotWantToHandle ex)
    {
        // suppress all other exceptions
    }
    catch (Exception ex)
    {
        // handle it
    }

    好,不好?


    只抓住你需要解决的问题,然后离开

    1
    2
    3
    catch(Exception e)
    {
    }

    对于其他所有(或跳过它,并将此异常提供给堆栈)