我刚刚看到一个关于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块通常被放入,因为编码器并不真正知道他们在做什么。在我的组织中,一个空的catch块必须包含一个注释,说明为什么不处理异常是一个好主意。

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

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

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

在某些情况下,您可能会使用它们,但它们应该非常不频繁。我可能会使用它的情况包括:

异常日志记录;根据上下文的不同,您可能希望发布一个未处理的异常或消息。 循环技术情况,如渲染或声音处理或列表框回调,行为本身将演示问题,抛出异常将只是阻碍,记录异常可能只会导致1000个“失败到XXX”消息。 不能失败的程序,尽管它们至少应该记录一些东西。

对于大多数winforms应用程序,我发现对于每个用户输入都有一个try语句就足够了。我使用以下方法:(AlertBox只是一个快速的消息框。显示包装)

  public static bool TryAction(Action pAction)
  {
     try { pAction(); return true; }
     catch (Exception exception)
     {
        LogException(exception);
        return false;
     }
  }

  public static bool TryActionQuietly(Action pAction)
  {
     try { pAction(); return true; }
     catch(Exception exception)
     {
        LogExceptionQuietly(exception);
        return false;
     }
  }

  public static void LogException(Exception pException)
  {
     try
     {
        AlertBox(pException, true);
        LogExceptionQuietly(pException);
     }
     catch { }
  }

  public static void LogExceptionQuietly(Exception pException)
  {
     try { Debug.WriteLine("Exception: {0}", pException.Message); } catch { }
  }

然后每个事件处理程序都可以这样做:

  private void mCloseToolStripMenuItem_Click(object pSender, EventArgs pEventArgs)
  {
     EditorDefines.TryAction(Dispose);
  }

or

  private void MainForm_Paint(object pSender, PaintEventArgs pEventArgs)
  {
     EditorDefines.TryActionQuietly(() => Render(pEventArgs));
  }

理论上,您可以使用tryactionsilent,它可能更适合呈现调用,这样异常就不会生成无穷无尽的消息。