49

我正在实现一个可以是只读或非只读的自定义集合实现;也就是说,所有改变集合的方法都调用一个道德等价的函数:

private void ThrowIfReadOnly() {
    if (this.isReadOnly)
       throw new SomeException("Cannot modify a readonly collection.");
}

我不确定在这种情况下应该使用哪个NotSupportedExceptionInvalidOperationException我应该使用哪个。

4

1 回答 1

68

MSDN 关于这个精确的主题只有一点指导,关于NotSupportedException

对于对象有时可以执行请求的操作的场景,并且对象状态决定了该操作是否可以执行,请参见InvalidOperationException

以下纯粹是我自己对规则的解释:

  • 如果对象的状态可以改变,使得操作在对象的生命周期内变得无效/有效,那么InvalidOperationException应该使用。
  • 如果操作在整个对象的生命周期内始终无效/有效,NotSupportedException则应使用。
  • 在这种情况下,“生命周期”意味着“任何人都可以获得对该对象的引用的整个时间”——也就是说,即使在Dispose()通常使大多数其他实例方法无法使用的调用之后;
    • 正如 Martin Liversage 所指出的,在对象已被处置的情况下,ObjectDisposedException应使用更具体的类型。(这仍然是 的子类型InvalidOperationException)。

在这种情况下,这些规则的实际应用如下:

  • 如果isReadOnly只能在创建对象时设置(例如构造函数参数),而不能在任何其他时间设置,那么NotSupportedException应该使用。
  • 如果isReadOnly可以在对象的生命周期内改变,那么InvalidOperationException应该使用。
    • 然而,在实现集合的情况下, InvalidOperationExceptionvsNotSupportedException的意义实际上是没有意义的——鉴于IsReadOnlyMSDN 上的描述,唯一允许的行为IsReadOnly是它的值在集合初始化后永远不会改变。这意味着集合实例可以是可修改的或只读的 - 但它应该在初始化时选择一个并在其剩余生命周期中坚持使用它。
于 2012-10-01T08:28:48.237 回答