valor tipo sirve recorrer que para obtener numerico español enumerador enumerado enum dato crear c# enums

c# - tipo - ¿Por qué está bien que una enumeración tenga dos nombres diferentes con el mismo valor numérico?



recorrer enum c# (16)

Acabo de descubrir un error sutil en el que tenía una enumeración con dos nombres compartiendo involuntariamente el mismo valor numérico (en este caso rojo = 10 y carmesí = 10). Estoy un poco sorprendido de que esto no sea un error de sintaxis.

public enum Colour { Red=10, Blue=11, Green=12, Crimson=10 } // Debug.Write(Colour.Red==Colour.Crimson) outputs True

¿Hay alguna razón en el mundo real por la que este comportamiento pueda ser útil o piense que debería ser un error de sintaxis?


¡Tener cuidado! Si su enum tiene varios elementos con el mismo valor, puede obtener resultados inesperados al usar Enum.Parse() . Al hacerlo, se devolverá arbitrariamente el primer elemento que tenga el valor solicitado. Por ejemplo, si tiene enum Car { Ford = 1, Chevy = 1, Mazda = 1} , entonces (Car)Enum.Parse(typeof(Car), "1") devolverá Car.Ford . Si bien eso podría ser útil (no estoy seguro de por qué lo sería), en la mayoría de las situaciones probablemente será confuso (especialmente para los ingenieros que mantienen el código) o se pasará por alto fácilmente cuando surjan problemas.


Algunas veces se recomienda (aunque no es recomendado por MS para C #! - vea el comentario de Salaros) incluir un límite inferior y superior en su enumeración como

public enum Colour { LowBound=10, Red=10, Rouge=10, Blue=11, Bleu=11, Green=12, Vert=12, Black=13, Noir=13, UpperBound=13 }

A los fines de validación / iteración a través de cada posible ajuste. Aunque tengo la sensación de que .Net puede proporcionar una facilidad para esto :)


Claro que sí, aunque quizás no sea demasiado común. Si hay una entidad / valor que se conoce comúnmente con dos nombres diferentes, entonces esa es una buena razón.

El escenario que ha presentado es quizás uno de esos casos. Una aún mejor, directamente de BCL, es la System.Windows.Forms.MessageBoxIcon enum; los miembros Stop , Error y Hand tienen la misma descripción y, de hecho, el mismo valor. Asterisk y la Information también son idénticos, como lo sugieren los comentarios:

Asterisk The message box contains a symbol consisting of a lowercase letter i in a circle. Information The message box contains a symbol consisting of a lowercase letter i in a circle.

Esperemos que esto le dé una buena idea de los escenarios apropiados (el suyo probablemente sea uno).


Creo que hay muchos usos para reutilizar el mismo número. Para dar un nuevo ejemplo, supongamos que tiene un sistema de clasificación que asegurará que los objetos de una clase particular (Padre) se creen antes que otras clases que dependen de él (Niños), puede que tenga algunos hijos que estén en el mismo nivel ''y no importa cuál se crea primero. En el ejemplo a continuación, los padres se crearían primero, los hijos 1, 2 o 3 a continuación, y el último sería Child4. Si esto fuera visto como un diagrama de árbol, cualquier ítem con el mismo número sería ''hermanos''.

public enum ObjectRanks { Parent = 0, Child1 = 1, Child2 = 1, Child3 = 1, Child4 = 2 }

Aunque puedo ver su punto de vista en que esto podría ser fácil de hacer por error. En ese caso, sería útil si Visual Studio tuviera la opción de habilitar las advertencias que le permitirían compilar, pero generaría una advertencia si se usara el mismo número dos veces.


El uso por valor nombrado en oposición al valor real es raíz. Supongamos que tiene francés, inglés, etc. con el mismo valor. Esta es la raíz de la enumeración para mí.


Enum es una enumeración de variables constantes, y puede tener dos elementos con el mismo valor, no hay ninguna razón para ser un error de sintaxis. Sin embargo, esto causará un error de compilación en este código.

switch(c) { Colour.Red: break; Colour.Crimson: break; ... }


Está bien. Podría tener dos valores que sean diferentes desde el punto de vista del usuario de una API, pero funcionalmente pueden tratarse como el mismo valor.


Este ejemplo mostrará por qué esto es útil. Cuando está trabajando en una biblioteca pública, que está dedicada al uso público, puede ser útil nombrar las mismas cosas de manera diferente.

public enum GestureType { Touch = 1, Tap = 1, DoubleTouch = 2, DoubleTap = 2, Swipe = 3, Slide = 3, ... }

Cuando diferentes palabras tienen el mismo significado en algunas situaciones, tiene sentido nombrarlas. Al analizar, siempre devuelve buen valor en esta situación.


Esto es válido y le permite a uno referir el mismo valor con nombres diferentes. Cuidado, esto funciona bien solo. Puede obtener resultados inconsistentes si está convirtiendo de int / string a enumeración o al formatear cadenas.

P.ej:

public enum Colour { Red=10, Blue=11, Green=12, Crimson=10 } Colour myColor = Colour.Crimson; Console.WriteLine("Crimson is {0}", myColor.ToString());

Salida:

Crimson is Red


He visto lo mismo en un .NET TWAIN wrapper: permite que todos los códigos de mensaje TWAIN se almacenen en una gran enumeración, pero al principio confunde un poco las cosas.


He visto que esta característica se usa a veces para un valor "predeterminado":

public enum Scope { Transient, Singleton, Default=Transient }

Pero presta atención, esto es solo azúcar para el usuario de tu enumeración. El hecho de que se llame Predeterminado no significa que sea el valor inicial.


Las enumeraciones se usan como constantes y definitivamente puedes tener dos constantes con el mismo valor que se usan en los mismos lugares. Puede ser así debido a la API de terceros, debido a la compatibilidad con versiones anteriores o simplemente debido a las reglas comerciales.


No es un error de sintaxis. Todo lo que hace una enum es enumerar una serie de constantes de una manera fuertemente tipada.

Por lo tanto, si un desarrollador escribe mal (como en su ejemplo), en lo que respecta a CLR, ese es un caso perfectamente válido. El CLR asume que el desarrollador sabe lo que está haciendo y por qué eligió hacerlo.

En cuanto a los casos del mundo real, no se me ocurre nada por el momento, pero sigo seguro de que probablemente haya ocasiones en las que sería útil.


Pensé que sería útil para la asignación de campos, por ejemplo (en LinqPad):

void Main() { ((FieldName)Enum.Parse(typeof(FieldName), "Name", true)).ToString().Dump(); ((FieldName)Enum.Parse(typeof(FieldName), "TaskName", true)).ToString().Dump(); ((FieldName)Enum.Parse(typeof(FieldName), "IsActive", true)).ToString().Dump(); ((FieldName)Enum.Parse(typeof(FieldName), "TaskIsActive", true)).ToString().Dump(); } public enum FieldName { Name, TaskName = Name, IsActive, TaskIsActive = IsActive }

El objetivo es usar el más corto de los nombres, sin embargo, los resultados de Parse o TryParse no son consistentes y este código genera:

TaskName TaskName IsActive IsActive


De la especificación de lenguaje c # :

Varios miembros de la enumeración pueden compartir el mismo valor asociado. El ejemplo

enum Color { Red, Green, Blue, Max = Blue }

muestra una enumeración en la que dos miembros de la enumeración, Blue y Max, tienen el mismo valor asociado.

En este caso, puede verificar MyColor == Color.Max, lo que sería útil en algunas circunstancias.


public enum Colour { Red=10, Rouge=10, Blue=11, Bleu=11, Green=12, Vert=12, Black=13, Noir=13 }