2010-07-01 21 views
9

Supongamos que tiene una enumeración que representa un código de error. Habrá varios códigos, cada uno con su propio valor int subyacente; sin embargo, el valor enum que obtiene el valor 0 predeterminado parece que debe considerarse cuidadosamente.C#: ¿El valor predeterminado de una enumeración debe ser Ninguno o Desconocido?

En el caso de un código de error enum, hay dos valores especiales que puedo pensar: Ninguno (para los casos cuando no hay error) y Desconocido (para los casos en que no existe un código de error existente, o incluso cuando el estado de error no puede ser detectado).

Uno de estos valores parece que debería obtener 0, donde el otro probablemente obtendrá algo más como -1. ¿Es más apropiado establecer el valor Ninguno en 0, o el valor Desconocido en 0?

public enum ErrorCode 
{ 
    None = -1, 
    Unknown = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 

public enum ErrorCode 
{ 
    Unknown = -1, 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 

Mi instinto me dice que el valor predeterminado debe ser Desconocido, pero me da curiosidad si alguien lo ha hecho de manera diferente.

Respuesta

4

Definitivamente no es una buena práctica. Pero si no hay otra manera ... entonces yo por lo general voy por la segunda opción:

public enum ErrorCode 
{ 
    Unknown = -1, 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 

0 va bien por la convención 'No Error' y -1 va bien con el entendimiento de que hay algún error (que puede ser desconocido).

+2

Gracias por responder la pregunta según las convenciones, y no distraerse por lo malo que es. – bwerks

2

¿Por qué devolver un valor de Código de error cuando no hay ningún error?

No tiene mucho sentido. Eliminar eso resolvería tu problema. Se podía hacer para ser 0 Unkown:

public enum ErrorCode 
{ 
    Unkown = 0, 
    InsufficientPermissions, 
    ConnectivityError 
} 

ACTUALIZACIÓN

Su comentario es un poco de miedo. Nunca debe tener un método que devuelva un tipo de ErrorCode. Es una práctica muy pobre. Dado que los ErrorCodes solo se deben devolver en circunstancias excepcionales, es una buena idea lanzar Excepciones.

Si lo desea, puede tener un campo en su Excepción personalizada que contenga el valor ErrorCode.

+0

Si la firma de su función es 'public ErrorCode DoFoo()', ¿qué devuelve cuando la función tuvo éxito? – Karmastan

+2

@Karmastan - Nunca tendré un método que devuelva un ErrorCode. Tendría una Excepción personalizada que se lanza y contiene el Código de Error dentro de eso. –

+2

El marco utiliza códigos de error cuando sabe que una operación puede fallar en circunstancias normales. Por ejemplo, Int32.TryParse devuelve un valor en lugar de lanzar una excepción. También uso códigos de error en los métodos de validación en los que estoy esperando un problema. En este caso, tener un error no es una excepción, es el uso previsto. –

15

Ya que está etiquetando su pregunta con las mejores prácticas: no use códigos de error cuando puede usar excepciones.

+0

Otra publicación relacionada con este problema: [Excepciones o códigos de error] (http://stackoverflow.com/questions/253314/exceptions-or-error-codes) – Karmastan

+4

Puede usar códigos de excepción y de error para eliminar ambigüedades y proporcionar un medio para hacer referencia a un error específico en la documentación. –

+3

Un error no es necesariamente una ocurrencia excepcional. El código de error puede ser el valor de retorno de un método Validate. –

6

En mi opinión, tanto Unknown como None significan lo mismo en el contexto de la enumeración ErrorCode. Mi razonamiento es que si estoy verificando un código de error es porque ya tengo un error.

También soy de la opinión de que una enumeración de código de error solo es útil en una excepción personalizada o como datos personalizados de un tipo de excepción existente y en ambos escenarios siempre tendrá un error.

+0

Esta llamada no es para mí, por desgracia; sin embargo, dado que estos valores se conservarán en una base de datos, tiene sentido incluir Desconocido como medio para traducir a nulo en la base de datos. Aunque, supongo que usar un nulo en ese caso también funcionaría. – bwerks

+0

¿Por qué no te llama? ¿Cómo puede cambiar los valores enum si no tiene acceso al código que capta las excepciones y devuelve códigos de error (para los errores Desconocidos en particular)? Si se trata de un problema político, por el amor a la justicia y la verdad, y al ahorro de dinero, señale los poderes que tienen esto y las publicaciones SO relacionadas para que puedan ver que la mayoría de los desarrolladores de software profesionales se oponen rotundamente a la devolución de códigos de error. – apollodude217

0

ErrorCodes malo. Excepciones buenas Pero para responder a la pregunta como se le preguntó:

Si su enumeración tiene un valor "Desconocido", debe ser el valor predeterminado.

+0

En primer lugar, los códigos de error a menudo se combinan con excepciones. En segundo lugar, es cortés ofrecer un método Validate para que el usuario pueda ver qué errores se producirían si se intentara alguna acción. Recuerde, las excepciones son costosas tanto en tiempo de CPU como en líneas de código. –

+0

@Jonathan, estoy de acuerdo, excepto que con la validación, ¿realmente lo llamarías "ErrorCodes?" Además, normalmente, la validación se produce a un nivel lo suficientemente alto como para poder usar constantes (o cadenas localizadas) para representar el error de validación. Si se pone lo suficientemente profundo en su estructura como para requerir un código, entonces realmente * es * una condición excepcional. –

+0

Solía ​​devolver cadenas, pero eso dificultaba la búsqueda y el filtrado.Entonces ahora tenemos un código de error para cada escenario además de las cadenas. Estos tampoco son errores de aplicación, estos son problemas de datos que un usuario de negocios necesitaría investigar y corregir manualmente. –

3

En primer lugar, no debe tener un código de error Ninguno. En cambio, llámalo "Éxito".

Ahora piense en cómo va a verificar el código de error. La mayoría de la gente espera algo como esto:

if (errorCode != Success) 

o que utilizan la taquigrafía

if (errorCode != 0) 

Así que ahí lo tienen. Su código de éxito es 0, no tiene un código de None y Desconocido puede ser cualquier cosa que desee.

0

Lo mismo de todos los "yo no lo haría respuestas", pero si insiste, aquí está mi $ 0,02.

ErrorCodes.None no tiene sentido, ya que no hay ningún error. ErrorCodes.Unknown no es útil. Intentan devolver un código de error anulable:

public ErrorCode? DoFoo() 

ya se puede comprobar NULL

var error = DoFoo(); 
if (error != null) 
    // react 

siendo mala, pero al menos le permite a no devuelve un código de error si no hay error.

+0

No estoy de acuerdo con esto. En primer lugar, FxCop nos dice que siempre debemos tener un valor "predeterminado" para cuando "la enumeración no se ha establecido explícitamente". Entonces, tener "Desconocido" o "Ninguno" es definitivamente apropiado. En segundo lugar, usando un Nullable o? la sintaxis socava un punto importante de tener una enumeración, para obligar al consumidor a elegir ¡ALGO! –

4

Supongo que no estaré de acuerdo con todos los demás en esto. "cuál es el estado actual de esta función"

No hay nada malo con los códigos de error cuando se utiliza en el sentido de

Para compensar un ejemplo: si tiene una carpeta temporal en red opcional, que se desea acceder, y desea mostrar los resultados de la última vez que intentó acceder a él, lo guardaría en un código de error. Quizás en una barra de estado quiera mostrar el estado actual al usuario.

Para mí, me gustaría utilizar ninguno como 0, como el valor predeterminado. No veo ninguna razón para hacer que Desconocido sea negativo. Desconocido es un estado de error perfectamente fino. Puedes ponerlo al final de la lista. En la práctica, he hecho

public enum ErrorCode 
{ 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
    Unknown, 
} 

Y para responder a su pregunta, digo Ninguno debe ser el valor por defecto. Ninguno significa: no existe ningún error del que tenga conocimiento. Desconocido significaría para mí: existe un error que es tan oscuro que no puedes contabilizarlo en tu código.

0

me habría importado que estar en desacuerdo con cualquier persona que dice que sólo debe utilizar excepciones. Al usar cualquier tipo de aplicación que utiliza una base de datos, es posible que desee almacenar estados para los datos en el sistema. Ya sean códigos de error o algún tipo de estado, están mejor representados en la base de datos como enteros.

uso y manejo de excepciones es una habilidad muy importante y se debe utilizar, pero yo creo que tener un código de error junto con las excepciones es generalmente una buena idea. No requiere demasiados recursos adicionales y se presta para ser utilizado en una aplicación conectada a la base de datos.

De hecho, me sugieren que el cambio "None" a "éxito" como se sugiere, pero que hacer "éxito" un valor de 1, y tienen todos los demás errores se incrementan a partir de ahí. El motivo es que, como estándar en la mayoría de las aplicaciones de bases de datos, las columnas de estado no aceptan nulos y, en general, se rastrean como números enteros. Esto puede generar problemas si usa un estado satisfactorio de 0 porque, de forma predeterminada, las columnas enteras que no aceptan nulos se establecerán en 0 si el usuario no inserta de forma explícita otra cosa. Esto daría lugar a un código de estado/error falso y causaría problemas en el futuro de su aplicación.No solo las variables enteras se inicializan automáticamente a 0 de forma predeterminada en C#, lo que hace que sea un éxito automático, también lo son las enumeraciones si no establece el valor inicial, y eso no es algo que desee.

También desde el punto de vista de codificación, un 1 también puede significar verdadero, y por lo tanto va bien con éxito. Sin embargo, hay situaciones en las que este puede no ser el caso. En los sistemas basados ​​en Unix, un retorno de 0 significa éxito/no hay errores, y en otros lenguajes como C++, un retorno 0 es estándar desde la función principal que también indica una ejecución exitosa de la función principal.

Cuestiones relacionadas