sintaxis - que tipos de excepciones existen en c#
¿Qué excepción arrojar sobre el estado de objeto no válido? (2)
Debe lanzar InvalidOperationException
para indicar que un objeto tiene un estado no válido.
De la documentación de MSDN (vinculada arriba):
La excepción que se produce cuando una llamada a un método no es válida para el estado actual del objeto.
Esta pregunta ya tiene una respuesta aquí:
Siempre me perdí un tipo de excepción integrado en c # que indicaría que un objeto está dañado. ¿Qué arrojas en tales casos?
Normalmente lo extraño cuando me doy cuenta de que un método, que se supone que funciona en un objeto, fallaría si el objeto tuviera un cierto estado. En tales situaciones, a menudo sospecho que este estado probablemente no se llegará nunca. Pero a la defensiva al respecto, me gustaría lanzar una excepción por si acaso (por ejemplo, después de un cambio de código en el futuro).
Para los argumentos del método, tenemos ArgumentException
por lo que podemos denegar parámetros no válidos. Pero para el estado del objeto? En Java usaría IllegalStateException
.
Por supuesto, podría argumentar que los métodos, que en realidad están cambiando el estado, podrían verificar la corrección del estado. ¿Y deberían hacerlo mejor, pero luego si no lo hacen (digamos en las clases de dioses heredadas)?
Editar:
Aunque InvalidOperationException
parece ser la mejor InvalidOperationException
, como dice la respuesta aceptada (y también esta ), tenga en cuenta:
Es sutil, pero semánticamente tiene un significado diferente a InvalidOperationException
. InvalidOperationException
indica un problema en el "protocolo" del objeto, que la persona que llama debe obedecer (p. Ej., No inicializado, cerrado ya, ...). En mi caso, la persona que llama no hizo nada incorrecto, es el objeto que está roto. Me gustaría transportar exactamente ese mensaje.
Ejemplo:
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);
}
El análogo más cercano que puedo encontrar a partir de .Net 2.0 [se puede haber agregado algo mejor desde] sería ObjectDisposedException
, que indica que un objeto ha sido colocado en un estado permanentemente inválido . Tal excepción se puede considerar "inesperada", pero eso es bueno, ya que la condición que indica sería igualmente inesperada. Además, si un método en un objeto descubre que su estado es inválido, luego de capturar tanta información sobre el estado del objeto como pueda ser útil para la resolución de problemas, coloque deliberadamente el objeto en un estado permanentemente inválido para que todas las operaciones futuras en él (que no sean, tal vez, solicitudes para extraer la información que se capturó con fines de solución de problemas) lanzará una excepción.
Debido a la fuerte asociación entre IDisposable
y ObjectDisposedException
, puede ser mejor definir un nuevo tipo de excepción que puede o no heredarse de ObjectDisposedException
. Podría decirse que ObjectDisposedException
debería haberse derivado de una ObjectInvalidatedException
, que también debería tener CorruptObjectDiscoveredException
y CorruptObjectInvalidatedException
[la primera siendo lanzada por el primer método que encuentra la corrupción, y la última por las llamadas al método subsiguiente en el mismo objeto], pero yo no soy Seguro que realmente importa.
Lo que es más importante, creo, es garantizar que el código que tiene motivos para creer que un objeto puede estar en un estado corrupto invalida expresamente el objeto. Algunas personas han sugerido que los métodos que descubren problemas inesperados deberían intentar derribar todo el sistema. Estoy totalmente en desacuerdo con esa filosofía. Si un método coloca un objeto en lo que se supone que es un estado corrompido temporalmente y luego sale por una excepción antes de que se pueda reparar el estado del objeto, debe invalidar el objeto por completo en lugar de dejarlo corrompido. Si después de desenrollar la pila, el sistema no puede funcionar sin el objeto ahora invalidado, se vendrá abajo rápidamente (una mejor alternativa que funcionar con un estado dañado). Sin embargo, si el proceso de desenrollar la pila hace que se abandone el objeto dañado (por ejemplo, alguien intentó cargar un documento de un archivo del tipo incorrecto, causando una excepción dentro de un método llamado por LoadDocument
), el hecho de que ahora el objeto abandonado estaba dañado puede ser información útil para comprender por qué se lanzó una excepción, pero puede no tener implicaciones negativas para la salud general del sistema.