c# enums ambiguous-grammar

¿Cómo se resuelven los valores de enumeración ambiguos en C#?



enums ambiguous-grammar (1)

Revisé la sección de la especificación del lenguaje C # con respecto a las enumeraciones, pero no pude explicar la salida del siguiente código:

enum en { a = 1, b = 1, c = 1, d = 2, e = 2, f = 2, g = 3, h = 3, i = 3, j = 4, k = 4, l = 4 } en[] list = new en[] { en.a, en.b, en.c, en.d, en.e, en.f, en.g, en.h, en.i, en.j, en.k, en.l }; foreach (en ele in list) { Console.WriteLine("{1}: {0}", (int)ele, ele); }

Produce:

c: 1 c: 1 c: 1 d: 2 d: 2 d: 2 g: 3 g: 3 g: 3 k: 4 k: 4 k: 4

Ahora, ¿por qué seleccionaría el tercer "1", el primer "2" y el "3", pero el segundo "4"? ¿Es este comportamiento indefinido, o me falta algo obvio?


Esto se documenta específicamente como un comportamiento indocumentado.

Probablemente haya algo en la forma en que se escribe el código que terminará eligiendo la misma cosa cada vez, pero la documentación de Enum.ToString dice esto:

Si varios miembros de la enumeración tienen el mismo valor subyacente e intenta recuperar la representación de cadena del nombre de un miembro de la enumeración en función de su valor subyacente, su código no debe hacer ninguna suposición sobre el nombre que devolverá el método.

(mi énfasis)

Como se mencionó en un comentario, un tiempo de ejecución .NET diferente puede devolver valores diferentes, pero todo el problema con el comportamiento indocumentado es que es propenso a cambiar por ninguna razón (aparentemente) buena. Podría cambiar según el clima, la hora, el estado de ánimo del programador o incluso en una revisión del tiempo de ejecución de .NET. No puedes confiar en el comportamiento indocumentado .

Tenga en cuenta que en su ejemplo, ToString es exactamente lo que quiere ver ya que está imprimiendo el valor, que a su vez lo convertirá en una cadena.

Si intenta hacer una comparación, todos los valores de enumeración con el mismo valor numérico subyacente son equivalentes y no puede saber cuál almacenó en una variable en primer lugar.

En otras palabras, si haces esto:

var x = en.a;

no hay forma de deducir después que escribiste en.a y no en.b o en.c ya que todos se comparan de la misma forma, todos tienen el mismo valor subyacente. Bueno, salvo crear un programa que lea su propia fuente.