2009-07-02 11 views
14

Tengo un método que toma una ruta de directorio como una cadena. Al comienzo del método, comprueba si existe esta ruta y, si no, debería lanzar una excepción. Estoy pensando que debería lanzar un DirectoryNotFoundException o algo así en lugar de un ArgumentException menos específico.C#: ¿Debo arrojar una ArgumentException o una DirectoryNotFoundException?

He leído la documentación de MSDN de ese DirectoryNotFoundException y se dice que

DirectoryNotFoundException utiliza el HRESULT COR_E_DIRECTORYNOTFOUND que tiene el valor 0x80070003.

No sé lo que eso significa exactamente, y se ve un poco de miedo ... debería todavía tirar esa excepción, o debería atenerse a un habitual ArgumentException? ¿O debería seguir el ArgumentException simplemente porque es un argumento del que me quejo? ¿O?

public void MakeFunOf(string path) 
{ 
    if(!Directory.Exists(path)) 
     throw new WhatException(); 
    TellJokeAbout(path); 
    PointAndLaughAt(path); 
} 
+1

+1 para codesnippet – Natrium

+0

No tenga miedo de HRESULT excepción, valor realmente toda excepción en .NET ha hresult su interior. – arbiter

+0

¿Qué hace HRESULT? – Svish

Respuesta

16

Si espera que el desarrollador compruebe la existencia del directorio antes de llamar a su método, use ArgumentException. Si desea que el desarrollador tenga la opción de manejar el directorio que falta, use la excepción DirectoryNotFound.

En otras palabras, "¿Es un error que el desarrollador me dijo que accediera a un directorio que no existía?"

Personalmente, utilizaría la excepción DirectoryNotFound.

+1

Estoy de acuerdo. InvalidArgument debería ser para una ruta que no es válida, no solo falta. Por lo tanto, "c :: \ x.txt" podría no ser válido, pero "c: \ x.txt" no lo es, independientemente de si existe. – paxdiablo

+1

Eso es complicado ... el directorio podría haberse eliminado entre el desarrollador que realiza la comprobación y pasa la ruta del directorio al método, por lo que nunca puede ser realmente un error que un método se pase a un directorio no existente como no hay una manera real de garantizar que seguirá estando allí una vez que se llame al método. – Rob

1

Es sólo mi opinión (como no tengo nada concreto que una copia de seguridad), pero aquí están mis razones para lanzando DirectoryNotFoundException en lugar de ArgumentException:

  • que debe desechar el tipo más específico/precisa de Excepción que puede permitir que el consumidor de su código comprenda la razón por la cual se lanzó la excepción.
  • Dado que los métodos del Marco se lanzar una DirectoryNotFoundException al intentar y hacer algo con un directorio que no está presente, en lugar de un ArgumentException, siga el bejaviour del Marco
1

suena como usted debe ser tirar un DirectoryNotFoundException como ArgumentException se utiliza mejor si no se proporciona el parámetro especificado ... es decir, es nulo.

Otra opción es crear su propia excepción y un tiro que en lugar decir

[Serializable] 
public class InvalidConfigurationException: Exception 
{ 
    public InvalidConfigurationException() : base() 
    { 
    } 

    public InvalidConfigurationException(string message) 
     : base(message) 
    { 
    } 

    public InvalidConfigurationException(string message, Exception innerException) 
     : base(message, innerException) 
    { 
    } 

    protected InvalidConfigurationException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 
} 

entonces se podría hacer:

public void MakeFunOf(string path) 
{  
    if(!Directory.Exists(path))   
     throw new InvalidConfigurationException('Directory entered was invalid or does not exist'); 
    TellJokeAbout(path);  
    PointAndLaughAt(path); 
} 
+0

Pero si el parámetro es nulo, entonces una ArgumentNullException sería más adecuada, ¿no? – Svish

+0

Sí ArgumentNullException sería más apropiado, solo estaba tratando de usar las Excepciones que optó en el mejor de los casos. Sin embargo, supongo que ArgumentException sería más apropiado si el directorio ingresado no fuera válido, es decir, el comentario de Pax sobre la respuesta de Talljoe. De todos modos, ¡me alegra que hayas resuelto el problema! – James

0

En referencia a la documentación de 'ArgumentException':

ArgumentException se lanza cuando se invoca un método y al menos uno de los argumentos pasados ​​no lo hace cumplir con la especificación del parámetro del método llamado. Todas las instancias de ArgumentException deben llevar un mensaje de error significativo que describa el argumento no válido, así como el rango esperado de valores para el argumento.

Al pie de la letra esto significa que la elección de la excepción depende de la especificación/documentación de su método.

Si el parámetro de ruta se documenta como algo así como 'ruta a un archivo/directorio existente', entonces estaría justificado en el lanzamiento de un 'ArgumentException' (o derivado) porque en el fondo, en virtud de la documentación que haya tomado la llamante responsable de garantizar que el archivo esté realmente allí.

Si el parámetro de ruta se documenta de manera más general como 'Ruta a un archivo a broma alrededor y se ríen de', entonces yo diría 'DirectoryNotFoundException' es más apropiado.

+0

Admitiré sin embargo que esta distinción es probablemente más sutil de lo que a nadie le importará en el mundo real;) – jerryjvl

2

En mi opinión, debería verificar las correcciones del argumento y lanzar una ArgumentException luego, después de la comprobación, arrojar una excepción DirectoryNotFoundException. Es una gran diferencia si no se dio ningún argumento o solo se especificó una ruta incorrecta.

void CheckDir(string path) 
{ 
    if(String.IsNullOrEmpty(path)) 
    { 
    throw new ArgumentException("Path not specified."); 
    } 
    if(!Directory.Exists(path)) 
    { 
    throw new DirectoryNotFoundException(); 
    } 
} 
Cuestiones relacionadas