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

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


当前回答

我不会把事情延伸到说使用空catch块的人是一个糟糕的程序员,不知道他在做什么……

如果需要,我使用空捕捉块。有时我正在使用的库的程序员不知道他在做什么,甚至在没有人需要的情况下抛出异常。

例如,考虑一些http服务器库,如果服务器抛出异常,因为客户端已断开连接,index.html无法发送,我不会太在意。

其他回答

只有在确实出现异常时才应该抛出异常——发生了超出正常范围的事情。一个空的catch块基本上表示“一些不好的事情正在发生,但我只是不在乎”。这是个坏主意。

如果您不想处理异常,就让它向上传播,直到它到达一些可以处理它的代码。如果没有任何东西可以处理异常,则应该关闭应用程序。

在极少数情况下,这样做是合理的。在Python中,你经常会看到这样的结构:

try:
    result = foo()
except ValueError:
    result = None

所以它可能是OK的(取决于你的应用程序):

result = bar()
if result == None:
    try:
        result = foo()
    except ValueError:
        pass # Python pass is equivalent to { } in curly-brace languages
 # Now result == None if bar() returned None *and* foo() failed

在最近的一个. net项目中,我必须编写代码来枚举插件dll,以查找实现特定接口的类。相关的代码(在VB中。NET,对不起)是:

    For Each dllFile As String In dllFiles
        Try
            ' Try to load the DLL as a .NET Assembly
            Dim dll As Assembly = Assembly.LoadFile(dllFile)
            ' Loop through the classes in the DLL
            For Each cls As Type In dll.GetExportedTypes()
                ' Does this class implement the interface?
                If interfaceType.IsAssignableFrom(cls) Then

                    ' ... more code here ...

                End If
            Next
        Catch ex As Exception
            ' Unable to load the Assembly or enumerate types -- just ignore
        End Try
    Next

尽管在这种情况下,我承认在某个地方记录失败可能是一种改进。

我认为完全空的catch块是一个坏主意,因为没有办法推断忽略异常是代码的预期行为。在某些情况下,接受异常并返回false或null或其他值并不一定是坏事。.net框架有许多“try”方法都是这样操作的。根据经验,如果应用程序支持日志记录,则添加注释和日志语句。

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

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 block中要做什么,你可以只记录这个异常,但不要让它空着。

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