Me gusta usar: ArgumentException
, ArgumentNullException
, y ArgumentOutOfRangeException
.
También hay otras opciones que no se centran tanto en el argumento en sí, sino que juzgan la llamada en su conjunto:
InvalidOperationException
- El argumento puede estar bien, pero no en el estado actual del objeto. El crédito va a STW (anteriormente Yoooder). Vota su respuesta también.
NotSupportedException
- Los argumentos pasados son válidos, pero simplemente no son compatibles con esta implementación. Imagine un cliente FTP y le pasa un comando que el cliente no admite.
El truco consiste en lanzar la excepción que mejor exprese por qué el método no puede llamarse como está. Idealmente, la excepción debe ser detallada sobre lo que salió mal, por qué está mal y cómo solucionarlo.
Me encanta cuando los mensajes de error apuntan a ayuda, documentación u otros recursos. Por ejemplo, Microsoft dio un buen primer paso con sus artículos de KB, por ejemplo, "¿Por qué recibo un mensaje de error" Operación cancelada "cuando visito una página web en Internet Explorer?" . Cuando encuentra el error, lo señalan al artículo de KB en el mensaje de error. Lo que no hacen bien es que no te dicen por qué falló específicamente.
Gracias a STW (ex Yoooder) nuevamente por los comentarios.
En respuesta a su seguimiento, lanzaría un ArgumentOutOfRangeException
. Mire lo que dice MSDN sobre esta excepción:
ArgumentOutOfRangeException
se lanza cuando se invoca un método y al menos uno de los argumentos pasados al método no es una referencia nula ( Nothing
en Visual Basic) y no contiene un valor válido.
Entonces, en este caso, está pasando un valor, pero ese no es un valor válido, ya que su rango es 1–12. Sin embargo, la forma en que lo documenta deja en claro qué arroja su API. Porque aunque podría decir ArgumentOutOfRangeException
, otro desarrollador podría decir ArgumentException
. Hazlo fácil y documenta el comportamiento.
FormatException
: la excepción que se produce cuando el formato de un argumento no es válido o cuando una cadena de formato compuesto no está bien formada.Voté por la respuesta de Josh , pero me gustaría agregar una más a la lista:
Se debe lanzar System.InvalidOperationException si el argumento es válido, pero el objeto está en un estado en el que no se debe usar el argumento.
Actualización tomada de MSDN:
Digamos que su objeto tiene un método PerformAction (acción enmSomeAction), las enmSomeActions válidas son Abrir y Cerrar. Si llama a PerformAction (enmSomeAction.Open) dos veces seguidas, la segunda llamada debería arrojar la InvalidOperationException (ya que la resolución era válida, pero no para el estado actual del control)
Como ya está haciendo lo correcto al programar a la defensiva, tengo otra excepción que mencionar es ObjectDisposedException. Si su objeto implementa IDisposable, siempre debe tener una variable de clase que rastree el estado desechado; si su objeto ha sido desechado y se llama a un método, debe activar la excepción ObjectDisposedException:
Actualización: para responder a su seguimiento: es una situación un poco ambigua, y se complica un poco más por un tipo de datos genérico (no en el sentido de .NET Generics) que se utiliza para representar un conjunto específico de datos; una enumeración u otro objeto fuertemente tipado sería un ajuste más ideal, pero no siempre tenemos ese control.
Me inclinaría personalmente hacia ArgumentOutOfRangeException y proporcionaría un mensaje que indica que los valores válidos son 1-12. Mi razonamiento es que cuando habla de meses, suponiendo que todas las representaciones enteras de meses son válidas, entonces espera un valor en el rango de 1-12. Si solo ciertos meses (como los meses que tenían 31 días) fueran válidos, entonces no estaría lidiando con un Rango per se y arrojaría una Excepción Argument genérica que indicara los valores válidos, y también los documentaría en los comentarios del método.
fuente
Dependiendo del valor real y qué excepción se ajusta mejor:
ArgumentException
(algo está mal con el valor)ArgumentNullException
(el argumento es nulo mientras esto no está permitido)ArgumentOutOfRangeException
(el argumento tiene un valor fuera del rango válido)Si esto no es lo suficientemente preciso, simplemente deriva tu propia clase de excepción
ArgumentException
.La respuesta de Yoooder me iluminó. Una entrada no es válida si no es válida en cualquier momento, mientras que una entrada es inesperada si no es válida para el estado actual del sistema. Entonces, en el último caso, una
InvalidOperationException
es una opción razonable.fuente
argumento de excepción.
fuente
ArgumentException :
También existen algunas subclases para tipos específicos de invalidez. El enlace tiene resúmenes de los subtipos y cuándo deben aplicarse.
fuente
Respuesta corta:
ninguno
Respuesta más larga:
usar Argument * Exception (excepto en una biblioteca que es un producto encendido, como la biblioteca de componentes) es un olor. Las excepciones son manejar situaciones excepcionales, no errores, y no fallas del usuario (es decir, consumidor de API).
Respuesta más larga:
Lanzar excepciones para argumentos no válidos es grosero, a menos que escriba una biblioteca.
Prefiero usar aserciones, por dos (o más) razones:
Así es como se ve el manejo de la excepción nula (siendo sarcástico, obviamente):
Las excepciones se utilizarán cuando la situación se espera pero es excepcional (suceden cosas que están fuera del control del consumidor, como una falla de E / S). Argumento * La excepción es una indicación de un error y será (en mi opinión) manejada con pruebas y asistida con Debug.
Por cierto: en este caso particular, podría haber usado el tipo de mes, en lugar de int. C # se queda corto cuando se trata de escribir con seguridad (¡Aspecto # rulez!), Pero a veces puedes evitar (o detectar en el momento de la compilación) todos esos errores.
Y sí, MicroSoft está equivocado al respecto.
fuente
Existe una excepción ArgumentException estándar que podría usar, o podría subclasificar y crear la suya propia. Hay varias clases específicas de ArgumentException:
http://msdn.microsoft.com/en-us/library/system.argumentexception(VS.71).aspx
Cualquiera que funcione mejor.
fuente