C# 在无效对象状态上抛出什么异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16390154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:55:23  来源:igfitidea点击:

What exception to throw on invalid object state?

c#.netexception

提问by Igor Lankin

I always missed a built-in exception type in c# which would indicate that an object is corrupted. What do you throw in such cases?

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

Usually I miss it when I realize that a method, that is supposed to work on an object, would fail if the object had a certain state. In such situations I often suspect that this state probably won't be ever reached. But being defensive about it, I'd like to throw an exception just in case it will (e.g. after a future code change).

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

For method arguments we have ArgumentExceptionso we can deny invalid parameters. But for object state? In Java I'd use IllegalStateException.

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

Of course you could argue that the methods, that are actually changing the state, could check for state correctness. And they better should, but then if they don't (say in legacy god classes)?

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

Edit:

编辑:

Although InvalidOperationExceptionseems to be the best fit, as the accepted answer states (and also this one), please note:

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

It is subtle, but semantically this has a different meaning than InvalidOperationException. InvalidOperationExceptionindicates a problem in the "protocol" of the object, which the caller has to obey (e.g. not initialized, closed already, ...). In my case the caller did nothing wrong, it's the object that is broken. I would like to transport exactly that message.

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

Example:

例子:

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); 
}

采纳答案by Matthew Watson

You should throw InvalidOperationExceptionto indicate that an object has invalid state.

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

From the MSDN documentation (linked above):

从 MSDN 文档(上面链接):

The exception that is thrown when a method call is invalid for the object's current state.

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

回答by supercat

The closest analogue I can figure as of .Net 2.0 [something better may have been added since] would be ObjectDisposedException, which indicates that an object has been placed into a permanently-invalid state. Such an exception may be considered "unexpected", but that's a good thing, since the condition it is indicating would be likewise unexpected. Further, if a method on an object discovers that its state is invalid it should, after capturing as much information about the object's state as may be helpful for trouble-shooting, deliberately place the object into a permanently-invalid state so that all future operations on it (other than perhaps requests to extract the information that was captured for trouble-shooting purposes) will throw an exception.

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

Because of the strong association between IDisposableand ObjectDisposedException, it may be better to define a new exception type which may or may not inherit from ObjectDisposedException. Arguably, ObjectDisposedExceptionshould have been derived from an ObjectInvalidatedException, which should also have CorruptObjectDiscoveredExceptionand CorruptObjectInvalidatedException[the former being thrown by the first method which finds the corruption, and the latter by subsequent method calls on the same object], but I'm not sure it really matters.

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

What's most important I think is to ensure that code which has reason to believe that an object may be in a corrupt state expressly invalidate the object. Some people have suggested that methods which discover unexpected problems should attempt to bring down the whole system. I strongly disagree with that philosophy. If a method puts an object into what is supposed to be a temporarily-corrupted state and then exits via an exception before the object's state can be fixed, it should invalidate the object completely rather than leaving it corrupted. If after stack unwinding the system can't function without the now-invalidated object, it will come crashing down in short order (a better alternative than functioning with corrupted state). If, however, the process of unwinding the stack causes the corrupt object to be abandoned (e.g. someone tried to load a document from a file of the wrong type, causing an exception within a method called by LoadDocument), the fact that the now-abandoned object was corrupt may be useful information for understanding why an exception was thrown, but may carry no averse implications for the overall health of the system.

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