我刚刚看到一个关于try-catch的问题,哪些人(包括Jon Skeet)认为空catch块是一个非常糟糕的主意?为什么呢?在任何情况下,空接点都不是错误的设计决策吗?

我的意思是,例如,有时你想从某个地方(webservice,数据库)获得一些额外的信息,你真的不关心你是否会得到这个信息。所以你试着获取它,如果发生了什么,没关系,我只会添加一个“catch (Exception ignored){}”,仅此而已


当前回答

这可能从来都不是正确的事情,因为您正在默默地传递每个可能的异常。如果有您期望的特定异常,那么您应该测试它,如果它不是您的异常则重新抛出。

try
{
    // Do some processing.
}
catch (FileNotFound fnf)
{
    HandleFileNotFound(fnf);
}
catch (Exception e)
{
    if (!IsGenericButExpected(e))
        throw;
}

public bool IsGenericButExpected(Exception exception)
{
    var expected = false;
    if (exception.Message == "some expected message")
    {
        // Handle gracefully ... ie. log or something.
        expected = true;
    }

    return expected;
}

其他回答

一个空的catch块本质上是在说“我不想知道抛出了什么错误,我只是忽略它们。”

它类似于VB6的On Error Resume Next,除了异常抛出后try块中的任何内容将被跳过。

如果有东西坏了,这也没用。

通常空的try-catch是一个坏主意,因为您正在默默地接受一个错误条件,然后继续执行。偶尔这可能是正确的做法,但通常这是一个迹象,表明开发人员看到了异常,不知道该如何处理,因此使用空捕获来消除问题。

这就相当于在引擎警示灯上贴上黑色胶带。

我相信如何处理异常取决于您正在使用的软件的哪个层:

如果你不知道在catch block中要做什么,你可以只记录这个异常,但不要让它空着。

        try
        {
            string a = "125";
            int b = int.Parse(a);
        }
        catch (Exception ex)
        {
            Log.LogError(ex);
        }

我的意思是,例如,有时你想从某个地方(webservice,数据库)获得一些额外的信息,你真的不关心你是否会得到这个信息。所以你试着获取它,如果发生了什么,没关系,我只会添加一个“catch (Exception ignored){}”,仅此而已

因此,以您的示例为例,在这种情况下这是一个坏主意,因为您捕获并忽略了所有异常。如果您只捕获einfofromirrelevance sourcenotavailable并忽略它,那是可以的,但您没有。您还忽略了ENetworkIsDown,它可能重要,也可能不重要。你忽略了enetworkcardhasmelting和efpuhasdecisidthatoneplusoneisseventeen,它们几乎肯定是重要的。

如果将空捕获块设置为只捕获(并忽略)您知道不重要的某些类型的异常,则空捕获块不是问题。在这种情况下,最好压制并默默地忽略所有异常,而不停下来先检查它们是否是预期的/正常的/不相关的,这种情况非常罕见。

空的catch块通常被放入,因为编码器并不真正知道他们在做什么。在我的组织中,一个空的catch块必须包含一个注释,说明为什么不处理异常是一个好主意。

与此相关的是,大多数人不知道try{}块后面可以跟catch{}或finally{},只有一个是必需的。