在同一个catch块中捕获两个异常?

Rof*_*ion 43 .net c# exception-handling exception

我有一个方法可以抛出两个不同的异常,CommuncationExceptionSystemException.在这两种情况下,我都使用相同的三行代码块.

try {
 ...
}

catch (CommunicationException ce) {
   ...
}

catch {SystemExcetion se) {
   ... 
}
Run Code Online (Sandbox Code Playgroud)

有没有可能这样做?

try {
   ...
}

catch (CommunicationException ce, SystemException se) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后我就不用写这么多代码了.我知道我可以将异常处理提取到私有方法,但由于代码只有3行,因此方法定义将占用比正文本身更多的代码.

Man*_*ero 155

如果您可以将您的应用程序升级到C#6,那么您很幸运.新的C#版本已经实现了Exception过滤器.所以你可以这样写:

catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
    //handle it
}
Run Code Online (Sandbox Code Playgroud)

有些人认为这段代码是一样的

catch (Exception ex) {                
    if (ex is CommunicationException || ex is SystemException) {
        //handle it
    }
    throw;
}
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.实际上,这是C#6中唯一一个在以前版本中无法模拟的新功能.首先,重新投掷意味着比跳过捕获更多的开销.其次,它在语义上不等同.在调试代码时,新功能可以保持堆栈完好无损.如果没有此功能,崩溃转储就不那么有用甚至无用了.

请参阅CodePlex上有关此问题讨论.一个显示差异例子.

  • 正如投票反映的那样,这是对这个问题的更好答案.接受的答案正确地解决了给出的代码示例,但没有回答问题. (8认同)

arc*_*hil 27

事实上,你只能抓住SystemException它,它也会处理CommunicationException,因为CommunicationException它来源于SystemException

catch (SystemException se) {
   ... //this handles both exceptions
}
Run Code Online (Sandbox Code Playgroud)

  • 不,这不是一个好的做法,因为它会抓住大量例外.但正如丹尼尔所说,如果不是CommunicationException,你已经这样做了:) (11认同)
  • +1:在他的具体情况下,这将是要走的路.接得好! (3认同)
  • 是的,这是可能的,但这也是好的做法吗?我还会在没有明确知道的情况下捕获所有其他子类? (3认同)
  • 无论如何都可以这样做,因为您已经捕获了SystemException。 (2认同)

Dan*_*rth 12

不幸的是,没有办法.您使用的语法无效,并且无法像在switch语句中那样掉头.我认为你需要使用私有方法.

一个小的hacky解决方案将是这样的:

var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
    // code that throws
}
catch(CommuncationException ex)
{
    exceptionHandler(ex);
}
catch(SystemException ex)
{
    exceptionHandler(ex);
}
Run Code Online (Sandbox Code Playgroud)

你需要自己决定这是否有意义.


ale*_*exn 5

不,你不能这样做.我知道的唯一方法是捕获一般的异常,然后检查它是什么类型:

try
{
   ...
}
catch(Exception ex)
{
   if(ex is CommunicationException || ex is SystemException)
   {
      ...
   }
   else
   {
     ... // throw; if you don't want to handle it
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 这会更改异常的调用堆栈.不是你想要的. (4认同)