C# 比多个 Catch 块更优雅的异常处理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/791390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:17:07  来源:igfitidea点击:

More Elegant Exception Handling Than Multiple Catch Blocks?

c#.netexceptionerror-handling

提问by Aaron

Using C#, is there a better way to handle multiple types of exceptions rather than a bunch of ugly catch blocks?

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

What is considered best practice for this type of situation?

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

For example:

例如:

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

采纳答案by Reed Copsey

In my opinion, a bunch of "ugly" catch blocks IS the best way to handle that situation.

在我看来,一堆“丑陋”的 catch 块是处理这种情况的最佳方。

The reason I prefer this is that it is very explicit. You are explicitly stating which exceptions you want to handle, and how they should be handled. Other forms of trying to merge handling into more concise forms lose readability in most cases.

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

My advice would be to stick to this, and handle the exceptions you wish to handle explicitly, each in their own catch block.

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

回答by Kent Boogaart

Unfortunately, C# does not have user exception filterslike VB.NET, so you're limited to:

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

  1. Catching a common ancestor to all exceptions. This may or may not be what you want, because there may be other descendant exception types that you do not want to catch.
  2. Moving the exception handling logic into another method and calling that from each handler.
  3. Repeating the exception logic for each handler.
  4. Moving the exception handling logic into a language that supports filters, such as VB.NET.
  1. 捕捉所有异常的共同祖先。这可能是您想要的,也可能不是您想要的,因为可能存在您不想捕获的其他后代异常类型。
  2. 将异常处理逻辑移动到另一个方中并从每个处理程序调用它。
  3. 为每个处理程序重复异常逻辑。
  4. 将异常处理逻辑移动到支持过滤器的语言中,例如 VB.NET。

回答by DOK

I agree with Reed: this is the best approach.

我同意 Reed:这是最好的方。

I would add these comments:

我会添加这些评论:

Only catch something you're going to do something about. If you can't fix the problem, there's no point in catching a specific exception.

只抓住一些你打算做的事情。如果您无解决问题,那么捕获特定异常就毫无意义。

Don't overdo use of catch blocks. In many cases where you can't resolve the exception, it's best to just let the exception bubble up to a central point (such as Page_Error) and catch it there. Then, you log the exception and display a message to the user.

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

回答by Mash

Catch only what you need to resolve specifically and leave

只捕获您需要专门解决的问题并离开

catch(Exception e)
{
}

for everything else (or skip it and give this exceptions to the stack)

对于其他所有内容(或跳过它并将此异常添加到堆栈中)

回答by JP Alioto

You should check out the Enterprise Library Exception Handling block. It allows for much more fine grain control over exceptions through policies (wrapping policies, propagation policies, replacement policies, logging policies, etc.) You can use it to standardize the way you code an exception block and use configuration to handle precisely what happens with a particular type of exception.

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

回答by Mark Brackett

About the only other thing you can do is emulate VB.NET's exception filters:

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

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

Sometimes this is better, sometimes not. I'd mainly use it if there was some common logic I wanted in the handler, but the exceptions don't share a base type.

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

回答by stanleyxu2005

Is this way not good?

这种方式不好吗?

If you want to handle only one exception:

如果您只想处理一个异常:

try
{
    // Many types of exceptions can be thrown
}
catch (TheExceptionIWantToHandle ex)
{
    // handle it
}
catch (Exception ex)
{
    // suppress all other exceptions
}

If you want to handle all exceptions except one:

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

try
{
    // Many types of exceptions can be thrown
}
catch (TheExceptionIDoNotWantToHandle ex)
{
    // suppress all other exceptions
}
catch (Exception ex)
{
    // handle it
}

good, not good?

好不好?

回答by user94636

If you need to write a really big ammount of code like this I would suggest checking some AOPframework. I personally use PostSharp. Then you could hide all exception handling code into aspects.

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