32

Estoy implementando una implementación de colección personalizada que puede ser de solo lectura o no; es decir, todos los métodos que cambian la colección llamar a una función que es el equivalente moral de:Cuándo usar InvalidOperationException o NotSupportedException?

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

No estoy seguro de cuál de NotSupportedException o InvalidOperationException debo utilizar en ese caso.

Respuesta

43

El MSDN sólo tiene un poco de orientación sobre este tema preciso, en NotSupportedException:

Para los escenarios donde a veces es posible que el objeto para realizar la operación solicitada, y el estado del objeto determina si la operación puede realizarse, vea InvalidOperationException.

Lo que sigue es puramente mi propia interpretación de la norma:

  • Si el estado del objeto se puede cambiar para que la operación pueda ser válido/válido durante la vida del objeto, entonces InvalidOperationException debe ser utilizado.
  • Si la operación siempre es inválida/válida durante toda la vida del objeto, entonces se debe usar NotSupportedException.
  • En ese caso, "duración" significa "todo el tiempo que cualquiera puede obtener una referencia al objeto", es decir, incluso después de una llamada Dispose() que a menudo hace inutilizables la mayoría de los demás métodos de instancia;
    • Según lo indicado por Martin Liversage, en el caso de que un objeto haya sido eliminado, se debe utilizar el tipo más específico ObjectDisposedException. (Eso sigue siendo un subtipo de InvalidOperationException).

La aplicación práctica de estas reglas en ese caso sería la siguiente:

  • Si isReadOnly puede fijarse únicamente en el momento en que se crea el objeto (por ejemplo, un argumento del constructor), y nunca en otro momento, entonces se debe usar NotSupportedException.
  • Si isReadOnly puede cambiar durante la vida útil del objeto, entonces se debe usar InvalidOperationException.
    • Sin embargo, el punto de InvalidOperationException vs NotSupportedException es realmente discutible en el caso de la implementación de una colección - dada la descripción de IsReadOnly en MSDN, el único comportamiento permitido para IsReadOnly es que su valor nunca cambia después de que se inicializa la colección. Lo que significa que una instancia de colección puede ser modificable o de solo lectura, pero debe elegir una en la inicialización y atenerse a ella durante el resto de su vida útil.
+5

Llamar a un método en un objeto desechado debe lanzar 'ObjectDisposedException' en lugar de' InvalidOperationException' a pesar de que se trata de una operación no válida. –

+3

@Martin: ¡Oh, qué lindo! No sabía nada de 'ObjectDisposedException' en absoluto.(Y como 'ObjectDisposedException' es un subtipo de' InvalidOperationException', se relaciona muy bien con ser un caso particular de 'InvalidOperationException') –

+0

¿Qué tal algo como: bool SomeMethod (param) { if (param en algún estado A) devolver algún control específico; if (param en algún estado B) devuelve otra verificación específica; throw new NotSupportedException(); } Si alguien agregó otro estado posible que podría alcanzarse al invocar este método, el desarrollador debería agregar una tercera instrucción if. Entonces, para mí llegar a la última línea del método es una excepción no admitida. ¿Qué piensas? – Skychan

Cuestiones relacionadas