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

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


当前回答

这与“不要使用异常来控制程序流”和“只在异常情况下使用异常”是密切相关的。如果执行了这些操作,那么只有在出现问题时才会出现异常。如果出现了问题,你也不想默默地失败。在不需要处理问题的罕见异常中,您至少应该记录异常,以防异常不再是异常。比失败更糟糕的是默默的失败。

其他回答

你不应该有一个空的catch块。这就像隐藏一个你知道的错误。至少,您应该为日志文件编写一个异常,以便稍后在时间紧迫时查看。

这与“不要使用异常来控制程序流”和“只在异常情况下使用异常”是密切相关的。如果执行了这些操作,那么只有在出现问题时才会出现异常。如果出现了问题,你也不想默默地失败。在不需要处理问题的罕见异常中,您至少应该记录异常,以防异常不再是异常。比失败更糟糕的是默默的失败。

一般来说,这是一个坏主意,因为这是一个真正罕见的情况,即失败(更普遍的情况是例外情况)没有得到任何回应。最重要的是,空捕获块是使用异常引擎进行错误检查的人使用的常用工具,他们应该先发制人地进行错误检查。

说它总是不好是不真实的……这种情况很少发生。在某些情况下,您不关心是否存在错误,或者错误的存在以某种方式表明您无法对其采取任何措施(例如,当将以前的错误写入文本日志文件时,您得到一个IOException,这意味着您无论如何都不能写出新的错误)。

第65项:不要忽视有效Java的例外:

空的catch块无法实现异常的目的 至少,catch块应该包含一个注释,解释为什么忽略异常是合适的。

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

异常日志记录;根据上下文的不同,您可能希望发布一个未处理的异常或消息。 循环技术情况,如渲染或声音处理或列表框回调,行为本身将演示问题,抛出异常将只是阻碍,记录异常可能只会导致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,它可能更适合呈现调用,这样异常就不会生成无穷无尽的消息。