7

我刚刚在一个项目中发现:

try
{
    myLabel.Text = school.SchoolName;
}
catch
{
    myPanel.Visible = false;
}

我想与开发人员交谈,而不是写这篇文章,说引发 null 异常(因为school理论上可能是 null ,而不是myLabel)实际上会使计算机发出三声哔哔声并休眠两秒钟。但是,我想知道我是否记错了规则。显然,这不是 try/catch 的预期用途,但这是因为它违背了意图,还是因为性能考虑而变得糟糕?我觉得这很糟糕,但我想说的不仅仅是“那真的很糟糕”。

4

9 回答 9

21

您不应该仅仅因为它是糟糕的设计而对控制流使用异常。这没有意义。例外是针对例外情况,而不是针对正常流程。在这种情况下,性能可能不会成为问题,因为对于现代硬件上的大多数现代应用程序,您可能会整天抛出异常,而用户不会注意到性能下降。但是,如果这是一个处理大量数据或执行大量某种工作的高性能应用程序,那么是的,性能将是一个问题。

于 2009-08-26T16:53:15.487 回答
9

在我看来,这很糟糕,因为使用 if 语句可以更清楚地说明:

if (school != null) {
    myLabel.Text = school.SchoolName;
}
else {
    myPanel.Visible = false;
}

这肯定会避免不必要地使用异常处理并使代码的含义非常明显。

于 2009-08-26T17:02:50.647 回答
8

我认为这很糟糕,因为它是针对一个异常进行编码的,而且它还会继承不必要的开销。仅当要以特定方式处理异常时才应捕获异常。

应该专门针对无法预测的异常情况捕获异常,在这种情况下,只需检查学校是否可以为空,实际上预计学校可能为空(因为标签没有设置)。如果 school 是 null 并且它不应该是 null,那么它应该抛出它自己的 ArgumentNullException。

于 2009-08-26T16:50:33.667 回答
3

异常确实会产生运行时开销,但在这里可能可以忽略不计。在调试器中运行会有所不同,但构建的二进制文件应该以几乎相同的速度运行。

告诉您的开发人员,任何黑猩猩都可以编写机器可以读取的代码。好的代码是为人类而不是机器编写的。如果 null 异常是您唯一担心的事情,那么它可能是用户代码中的错误——没有人应该尝试以这种方式将 null 分配给任何东西。改为使用Assert()语句。

于 2009-08-26T16:54:31.273 回答
2

你说这很糟糕是绝对正确的。这很糟糕,因为它违背了意图并且损害了性能。

我意识到不同的编程风格是有空间的,但就个人而言,我认为即使这样可行,并且我可以看到代码试图做什么,它也会损害可读性和代码清晰度,从而使维护变得更加困难程序员跟随。if 语句在这里更合适。

于 2009-08-26T16:53:40.900 回答
2

抛出异常确实会对性能产生负面影响,请参阅http://msdn.microsoft.com/en-us/library/ms229009(VS.80).aspx

于 2009-08-26T16:53:47.700 回答
1

我从不喜欢使用异常进行流控制。异常是昂贵的,并且很难确定程序的实际流程是什么,异常被抛出以到达代码中的其他地方。对我来说,这就像使用 GoTo。这并不意味着您应该避免异常,而是异常应该只是程序中通常应该发生的事情的异常。

我认为代码中更糟糕的部分是它甚至没有做任何异常。没有日志记录,甚至没有解释为什么抛出异常。

于 2009-08-26T16:52:53.693 回答
1

查看这篇关于“为什么不使用异常作为常规控制流?”的帖子

于 2009-08-26T17:03:54.967 回答
1

我同意这里的每个人——这是一个可怕的想法。

在 Java 中有一些案例(我认为它们现在大部分都消失了,但外部库中可能仍然有一些)要求您为某些“非异常”案例捕获异常。

一般来说,在编写库代码(实际上是任何类)时,避免对任何可能避免的异常使用异常。如果可能未设置名称字段并且应该在 write() 方法中导致异常,请确保添加 isValid() 方法,以便您实际上不必捕获 write 周围的异常即可知道有一个问题。

(糟糕的 Java 代码附录):这种“好”的编程风格实际上消除了 Java 中对检查异常的任何需求,而 Java 中的检查异常就是烂。

于 2009-08-26T17:14:21.047 回答