关于C#:用完全相同的代码合并catch块?

Merge catch blocks with exactly the same code?

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

出于代码重用的原因,我希望合并以下代码中的catch块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
{
    HandleKnownException1(ex);
}
catch (InvalidDataException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
{
    HandleKnownException2(ex);
}
catch (ArithmeticException ex)
{
    HandleKnownException2(ex);
}
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
catch (InvalidDataException ex)
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
catch (ArithmeticException ex)
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

这有可能吗?

谢谢。


大概你在不止一个地方做的。如果是这样,为什么不这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
    DoSomeInputOutput();
}
catch (Exception ex)
{
    HandleInputException(ex);
}

void HandleInputException(Exception ex)
{
   if (ex is InvalidOperationException || ex is InvalidDataException || ex is ArgumentNullException)
   {
     HandleKnownException1 (ex);
   }
   else if ...
   else if ...
}

不(或者至少:除非您希望分组的异常恰好共享一个特定于该组的公共基类,在您的示例中不是这样);在这个场景中,您唯一能做的就是catch (Exception ex)和在ex上执行运行时测试。当您这样做时,我希望您的代码已经像现在这样"更漂亮"(因为,重要的是,您已经将处理代码重构为一个方法)。

我会尝试调整间距,以便专注于重要的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try
{
    DoSomeInputOutput();
}
// blah humorous scenario 1
catch (InvalidOperationException ex) { HandleKnownException1(ex); }
catch (InvalidDataException ex) { HandleKnownException1(ex); }
catch (ArgumentNullException ex) { HandleKnownException1(ex); }
// blah whimsical scenario 2
catch (ArgumentOutOfRangeException ex) { HandleKnownException2(ex); }
catch (ArithmeticException ex) { HandleKnownException2(ex); }
catch (InvalidCastException ex) { HandleKnownException2(ex); }
// unexpected comedy
catch (Exception ex) { HandleUnknownException(ex); }

(或某物)。

在某些方面,这也与这个问题有关:切换/模式匹配思想。


如果您有一个适当的异常层次结构,那么您只能这样做,然后您可以捕获一个更高层次结构中类型的异常。然而,异常层次结构在设计上是相当浅的,不能保证您只基于层次结构以同样的方式处理异常。除此之外…对于您的示例中使用的标准异常类型,这些都没有帮助。