Enums y constantes. ¿Cuál usar cuando?

96

Estaba leyendo un poco sobre enumeraciones y las encuentro muy similares a declarar constantes. ¿Cómo sabría cuándo usar una constante en lugar de una enumeración o viceversa? ¿Cuáles son algunas de las ventajas de usar enumeraciones?

Draco
fuente
vea también stackoverflow.com/questions/11575376/… para una pregunta similar para Java (las respuestas también se aplican principalmente a C #).
Alexei Levenkov

Respuestas:

96

Use enumeraciones cuando desee definir un rango de valores que algo puede ser. El color es un ejemplo obvio como:

public enum Colour
{
    White,
    Red,
    Blue
}

O tal vez un conjunto de cosas posibles como: (Ejemplo, robé de aquí porque soy vago)

[FlagsAttribute]
enum DistributedChannel
{
  None = 0,
  Transacted = 1,
  Queued = 2,
  Encrypted = 4,
  Persisted = 16,
  FaultTolerant = Transacted | Queued | Persisted
}

Las constantes deben ser de un solo valor, como PI. No hay un rango de valores de PI, solo hay PI.

Otros puntos a considerar son:

  • a: Las constantes no necesariamente indican una relación entre las constantes, mientras que una enumeración indica que algo puede ser uno del conjunto definido por la enumeración.
  • b: Una enumeración definida puede ayudarlo con la verificación de tipos cuando se usa como argumento. Las constantes son solo valores, por lo que no proporcionan ninguna información semántica adicional.
Andrew Barrett
fuente
1
¿Qué pasa si terminas usando mucho .ToString()en la enumeración, cualquier valor en el uso de una clase con cadenas constantes que se ve y actúa como una enumeración pero elude una llamada a ToString()? Ejemplo
Sinjai
Espera, creo que respondí mi propia pregunta. El código de ese ejemplo no funcionaría: tendría que tomar la entrada como una cadena, que en realidad no se comportaría como una enumeración.
Sinjai
1
¿Por qué no puedes tener una clase estática Color con colores constantes en lugar de enumeración? ¿Cual es la diferencia?
WDUK
declaración breveType Safety"
ahmednabil88
31

Lo que falta en las otras respuestas es que las enumeraciones tienen un tipo de base entera. Puede cambiar el valor predeterminado de int a cualquier otro tipo integral excepto char como:

enum LongEnum : long {
    foo,
    bar,
}

Puede emitir explícitamente desde e implícitamente al tipo base, lo cual es útil en las sentencias switch. Tenga en cuenta que se puede convertir cualquier valor del tipo base en una enumeración, incluso si la enumeración no tiene ningún miembro con el valor apropiado. Por lo tanto, usar siempre la sección predeterminada en un conmutador es una buena idea. Por cierto, .NET en sí permite incluso enumeraciones con valor de punto flotante, pero no puede definirlas en C #, aunque creo que aún puede usarlas (excepto en el conmutador).

Además, el uso de enumeraciones le brinda más seguridad de tipos. Si tiene la intención de usar, por ejemplo, constantes int como parámetros de método, entonces podría llamar al método con cualquier valor int. Por supuesto, a través del casting también puede suceder con enumeraciones, pero no sucederá accidentalmente. Peor es la posibilidad de confundir el orden de los parámetros.

void method(int a, int b) {...}

Si la constante A solo puede entrar en ay la constante B solo puede entrar en b, entonces el uso de dos tipos de enumeración diferentes revelará cualquier uso indebido durante la compilación.

Johannes
fuente
21

Una constante es una característica del lenguaje que dice que la variable no cambiará el valor (para que el compilador pueda hacer optimizaciones en torno a ese conocimiento) donde una enumeración es de un tipo específico.

Las constantes pueden ser de cualquier tipo de datos, pero una enumeración es una enumeración.

Utilizo una enumeración en cualquier lugar donde pueda tener una serie de opciones y desee mejorar la legibilidad del código. es decir, podría tener niveles de seguimiento como un int con valores 0, 1, 2 o como una enumeración como error, advertencia e información.

Las enumeraciones también tienen la capacidad de utilizarse como operadores bit a bit, es decir, FontStyle.Bold | FontStyle.Italic le daría fuentes en negrita y cursiva.

Robert MacLean
fuente
8

Además de la respuesta de Robert:

  1. Use enum para un conjunto finito de valores con nombre. Realmente no le importa el valor numérico detrás de cada símbolo (pero aún tiene la capacidad de imponerlos, por ejemplo, por compatibilidad con un sistema heredado).

  2. Robert: Sí, los Enum se pueden usar como campos de bits. Utilice el atributo Flags (y asegúrese de que los miembros de la enumeración tengan valores numéricos adecuados).

Serge Wautier
fuente
3

La constante AC # es similar a una variable en que le da un nombre definido a un valor. Sin embargo, una constante difiere de una variable estándar porque una vez definida, el valor asignado a la constante nunca se puede cambiar. El principal beneficio de las constantes es su ayuda para crear código autodocumentado, así como permitir la declaración de valores clave en un solo lugar, lo que permite un fácil mantenimiento en caso de que sea necesario actualizar el valor y recompilar el software.

Mientras que las listas de enumeradores son útiles para definir secuencias y estados, particularmente cuando hay una progresión natural a través de esos estados. Esto se debe a que cada constante en la lista se puede formatear y comparar usando su nombre o valor. También se puede usar una enumeración para definir un conjunto limitado de valores válidos.

simplemente dura
fuente
3

Una cosa que encuentro útil cuando se usa en enumlugar de constes que puedes iterar a través de los valores en un enum, es mucho más difícil hacerlo con constvalores.

David Klempfner
fuente