Como os valores de enumeração ambíguos são resolvidos em c #?

Verifiquei a seção da especificação da linguagem C # em relação às enums, mas não consegui explicar a saída para o código a seguir:

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); } 

Ele produz:

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

Agora, por que selecionaria o terceiro “1”, o primeiro “2” e “3”, mas o segundo “4”? É este comportamento indefinido, ou estou faltando alguma coisa óbvia?

Isso é especificamente documentado como comportamento não documentado.

Provavelmente há algo na maneira como o código está escrito que acabará escolhendo a mesma coisa toda vez, mas a documentação do Enum.ToString afirma isso:

Se vários membros de enumeração tiverem o mesmo valor subjacente e você tentar recuperar a representação de seqüência de caracteres do nome de um membro de enumeração com base em seu valor subjacente, seu código não deve fazer suposições sobre qual nome o método retornará.

(minha ênfase)

Como mencionado em um comentário, um tempo de execução .NET diferente pode retornar valores diferentes, mas todo o problema com o comportamento não documentado é que ele está propenso a mudar por nenhuma razão (aparentemente) boa. Isso pode mudar dependendo do clima, da hora, do humor do programador ou mesmo de um hotfix para o tempo de execução do .NET. Você não pode confiar no comportamento não documentado .

Note que no seu exemplo, ToString é exatamente o que você quer ver, já que você está imprimindo o valor, que por sua vez o converterá em uma string.

Se você tentar fazer uma comparação, todos os valores de enum com o mesmo valor numérico subjacente serão equivalentes e você não poderá dizer qual deles você armazenou em uma variável em primeiro lugar.

Em outras palavras, se você fizer isso:

 var x = en.a; 

não há como deduzir depois que você escreveu en.a e não en.b ou en.c como todos se comparam iguais, todos eles têm o mesmo valor subjacente. Bem, falta criar um programa que leia sua própria fonte.