45

我总是错过了 c# 中的内置异常类型,这表明对象已损坏。在这种情况下你会扔什么?

通常当我意识到如果对象具有某种状态时应该对对象起作用的方法将失败时,我会想念它。在这种情况下,我经常怀疑这种状态可能永远不会达到。但是出于防御考虑,我想抛出一个异常以防万一(例如在未来的代码更改之后)。

对于我们拥有的方法参数ArgumentException,我们可以拒绝无效参数。但是对于对象状态呢?在 Java 中,我会使用IllegalStateException.

当然,您可以争辩说,实际上改变状态的方法可以检查状态的正确性。他们最好应该这样做,但如果他们不这样做(比如在传统的上帝课程中)?

编辑:

尽管InvalidOperationException似乎是最合适的,但正如接受的答案所述(以及这个),请注意:

它很微妙,但从语义上讲,它的含义与InvalidOperationException. InvalidOperationException表示对象的“协议”中存在问题,调用者必须遵守(例如,未初始化、已关闭……)。在我的情况下,调用者没有做错任何事情,它是被破坏的对象。我想准确地传输该消息。

例子:

switch(this._someType) {
  case SomeType.A: doSomething(); break;
  case SomeType.B: doSomethingElse(); break;
  /*...*/
  default:
    // Unexpected type! Someone introduced a new type and didn't update this.
    throw new IllegalStateException("Unknown type "+this._someType); 
}
4

2 回答 2

51

您应该 throwInvalidOperationException以指示对象具有无效状态。

从 MSDN 文档(上面链接):

当方法调用对于对象的当前状态无效时引发的异常。

于 2013-05-05T23:26:51.143 回答
0

我能想到的最接近 .Net 2.0 的类似物[可能已经添加了更好的东西] 是ObjectDisposedException,这表明一个对象已被置于永久无效状态。这种异常可能被认为是“意外的”,但这是一件好事,因为它所指示的条件同样是意外的。此外,如果对象上的方法发现其状态无效,它应该在捕获尽可能多的有关对象状态的信息后,可能有助于故障排除,故意将对象置于永久无效状态,以便所有未来操作在它上面(可能除了请求提取出于故障排除目的而捕获的信息之外)将引发异常。

由于 和 之间的强关联IDisposableObjectDisposedException最好定义一个新的异常类型,它可以继承也可以不继承ObjectDisposedException。可以说,ObjectDisposedException应该是从 an 派生的ObjectInvalidatedException,它也应该有CorruptObjectDiscoveredExceptionand CorruptObjectInvalidatedException[前者由发现损坏的第一个方法抛出,后者由对同一对象的后续方法调用抛出],但我不确定它是否真的很重要.

我认为最重要的是确保有理由相信一个对象可能处于损坏状态的代码明确地使该对象无效。有些人建议发现意外问题的方法应该尝试关闭整个系统。我强烈反对这种哲学。如果一个方法将一个对象置于应该是临时损坏的状态,然后在对象的状态可以修复之前通过异常退出,它应该使对象完全无效,而不是让它损坏。如果在堆栈展开后系统在没有现在无效的对象的情况下无法运行,它将在短时间内崩溃(比在损坏状态下运行更好的选择)。但是,如果展开堆栈的过程导致损坏的对象被丢弃(例如LoadDocument),现在被遗弃的对象已损坏的事实可能有助于理解为什么抛出异常,但可能不会对系统的整体健康产生不利影响。

于 2013-05-06T16:26:33.207 回答