应该使用多个catch块还是捕获基类Exception并使用is关键字处理它?

时间:2014-04-10 12:10:06

标签: c#

我正在做一个大学项目并且做了一个有异常处理的有趣行动。

我在try { } catch { }块中有一段代码。它可以抛出两种类型的异常,每种异常应该以不同处理。

在没有考虑的情况下,我写了这样的代码:

try
{
    SomeAction();
}
catch(Exception _Ex)
{
    if(_Ex is NullReferenceException) 
    {
        DoSomething();
    }
    else if(_Ex is ArgumentOutOfRangeException) 
    {
        DoSomethingElse();
    }
}

Hovewer我的教授说这是一种奇怪的方式,并且问为什么我没有使用这种结构:

try
{
    SomeAction();
}
catch(NullReferenceException _Ex)
{
    DoSomething();
}
catch(ArgumentOutOfRangeException _Ex)
{
    DoSomethingElse();
}

我不能不同意他这种方式也有效 - 甚至可能比我的方式更简单。所有这些让我思考 - 两种解决方案都是正确的,并做同样的事情。 如果是这样,哪一个应该被用作更好的做法?

我个人认为使用is的方法更好一些,因为它允许程序员通常处理异常情况,并且可以单独处理每个Exception导数。除此之外,我喜欢它看起来更像"语法上很好的方式"。

另一方面,多个catch版本是根据C#引用(http://msdn.microsoft.com/pl-pl/library/0yd65esw.aspx)工作的方式。

您认为这两种方法都可以接受,还是应该只使用其中一种? 如果是这样,哪一个赢了"?

我知道这不是地球上最重要的问题,但它让我很好奇。

2 个答案:

答案 0 :(得分:4)

你的教授是对的。 理想情况下,您应该只捕获您感兴趣的例外情况。

第一种方法中的缺陷是,它会捕获所有意外的异常,如ArgumentNullException在这种情况下,理想情况下,应用程序应该会因未处理的异常而崩溃。如果要记录信息,则应在记录后重新抛出所有其他异常。


此代码与教授的建议相同:

catch(Exception _Ex)
{
    if(_Ex is NullReferenceException) 
    {
        DoSomething();
    }
    else if(_Ex is ArgumentOutOfRangeException) 
    {
        DoSomethingElse();
    }
    throw;
}

答案 1 :(得分:3)

你的两个例子做了很多不同的事情。第一个捕获任何异常,只处理NullReferenceException和ArgumentOutOfRangeException,静默忽略所有其他情况。第二种情况只捕获和处理NullReferenceException和ArgumentOutOfRangeException,并留下任何其他异常由更高的catch块处理链。第二种情况是正确的,首先可能不是。这可能就是为什么你应该总是像第二种那样编码,所以你不要陷入你在第一种情况下设置的陷阱。