web-dev-qa-db-ja.com

InvalidOperationExceptionまたはNotSupportedExceptionを使用する場合

私は、読み取り専用または非読み取り専用のカスタムコレクション実装を実装しています。つまり、コレクションを変更するすべてのメソッドは、道徳的に同等の関数を呼び出します。

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

その場合、NotSupportedExceptionInvalidOperationExceptionのどちらを使用すればよいかわかりません。

39
Jean Hominal

MSDNには、この正確なトピックについて NotSupportedException に関するガイダンスが少しだけあります。

オブジェクトが要求された操作を実行できる場合があり、オブジェクトの状態によって操作を実行できるかどうかが決まるシナリオについては、「 InvalidOperationException 」を参照してください。

以下は、純粋に私自身のルールの解釈です。

  • オブジェクトの有効期間中に操作が無効/有効になるようにオブジェクトの状態が変化する可能性がある場合は、InvalidOperationExceptionを使用する必要があります。
  • オブジェクトの存続期間全体で操作が常に無効/有効である場合は、NotSupportedExceptionを使用する必要があります。
  • その場合、「寿命」は「誰でもオブジェクトへの参照を取得できる時間全体」を意味します。つまり、他のほとんどのインスタンスメソッドが使用できなくなるDispose()呼び出しの後でも、
    • Martin Liversageが指摘したように、オブジェクトが破棄された場合は、より具体的なObjectDisposedExceptionタイプを使用する必要があります。 (これはInvalidOperationExceptionのサブタイプです)。

その場合のこれらのルールの実際の適用は次のようになります。

  • isReadOnlyは、オブジェクトが作成されたときにのみ設定でき(たとえば、コンストラクター引数)、それ以外のときに設定できない場合は、NotSupportedExceptionを使用する必要があります。
  • オブジェクトの存続期間中にisReadOnlyが変更される可能性がある場合は、InvalidOperationExceptionを使用する必要があります。
    • ただし、コレクションを実装する場合、InvalidOperationExceptionNotSupportedExceptionのポイントは実際には重要ではありません-MSDNで IsReadOnly の説明を考えると、 IsReadOnlyで許可されている動作は、コレクションが初期化された後でその値が変更されないことだけです。コレクションインスタンスは変更可能または読み取り専用のいずれかである可能性があることを意味しますが、初期化時に1つを選択し、残りの存続期間中それを維持する必要があります。
55
Jean Hominal