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

时间:2011-04-06 08:20:42

标签: c# .net exception exception-handling

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

try {
 ...
}

catch (CommunicationException ce) {
   ...
}

catch {SystemExcetion se) {
   ... 
}

有可能这样做吗?

try {
   ...
}

catch (CommunicationException ce, SystemException se) {
   ...
}

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

8 个答案:

答案 0 :(得分:138)

如果您可以将您的应用程序升级到C#6,那么您很幸运。 The new C# version has implemented Exception filters。所以你可以这样写:

catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
    //handle it
}

有些人认为此代码与

相同
catch (Exception ex) {                
    if (ex is CommunicationException || ex is SystemException) {
        //handle it
    }
    throw;
}

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

查看discussion about this on CodePlex。还有example showing the difference

答案 1 :(得分:25)

事实上,您只能抓住SystemException,它也会处理CommunicationException,因为CommunicationException来自SystemException

catch (SystemException se) {
   ... //this handles both exceptions
}

答案 2 :(得分:11)

不幸的是,没有办法。您使用的语法无效,并且无法像在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);
}

如果这有任何意义,你需要自己决定。

答案 3 :(得分:5)

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

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

答案 4 :(得分:3)

怎么样?
try {


...
}

catch (CommunicationException ce) {
   HandleMyError(ce);
}

catch {SystemExcetion se) {
   HandleMyError(se);
}

private void HandleMyError(Exception ex)
{
// handle your error
}

答案 5 :(得分:3)

可能重复

Catch multiple exceptions at once?

我在这里引用答案:

 catch (Exception ex)            
       {                
           if (ex is FormatException ||
               ex is OverflowException)
           {
               WebId = Guid.Empty;
               return;
           }
           else
           {
               throw;
           }
       }

答案 6 :(得分:1)

由于您对两种类型的例外都做了同样的事情,您可以去:

try
{
    //do stuff
}
catch(Exception ex)
{
    //normal exception handling here
}

如果你需要为它做一些独特的事情,只捕获显式的Exception类型。

答案 7 :(得分:1)

将这个从历史深处拖上来,因为它碰巧出现在一些搜索结果中。

随着 C# 7.0(于 2017 年随 VS2017、.net framework 4.7 和 dotnet core 2.0 一起推出)的出现,您现在可以执行以下操作:

try {
   ...
}
catch (Exception e) when (e is CommunicationException || e is SystemException) {
   ...
}