抛出无效对象状态的异常是什么?

时间:2013-05-05 23:22:39

标签: c# .net exception

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

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

对于方法参数,我们有ArgumentException,因此我们可以拒绝无效参数。但对于对象状态?在Java中,我使用IllegalStateException

当然你可以争辩说,实际改变状态的方法可以检查状态的正确性。而且他们应该更好,但如果他们不这样做(比如传统的上帝班)?

修改

虽然InvalidOperationException似乎是最合适的,但正如接受的答案所述(以及this one),请注意:

这是微妙的,但在语义上它与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); 
}

2 个答案:

答案 0 :(得分:40)

您应该抛出InvalidOperationException以指示对象具有无效状态。

从MSDN文档(上面链接):

  

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

答案 1 :(得分:0)

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

由于IDisposableObjectDisposedException之间存在强关联,因此定义一个可能会或可能不会从ObjectDisposedException继承的新异常类型可能会更好。可以说,ObjectDisposedException应该来自ObjectInvalidatedExceptionCorruptObjectDiscoveredException也应该有CorruptObjectInvalidatedExceptionLoadDocument [前者被第一种发现腐败的方法抛出,而且后者通过后续方法调用同一个对象],但我不确定它真的很重要。

我认为最重要的是确保有理由相信对象可能处于损坏状态的代码明确地使对象无效。有人建议发现意外问题的方法应该试图打倒整个系统。我非常不同意这种哲学。如果一个方法将一个对象置于一个应该是一个临时损坏的状态,然后在对象的状态可以被修复之前通过异常退出,它应该完全使对象无效而不是让它被破坏。如果在堆栈展开后系统无法在没有现在无效的对象的情况下运行,它将在短时间内崩溃(比使用损坏状态更好的替代方案)。但是,如果解除堆栈的过程导致损坏的对象被丢弃(例如,有人试图从错误类型的文件加载文档,导致{{1}}调用的方法中的异常),事实现在被抛弃的对象是腐败的可能是有用的信息,用于理解抛出异常的原因,但可能对系统的整体健康状况没有任何负面影响。