Как решаются неоднозначные значения перечислений в C#?

Я проверил раздел спецификации языка C# относительно перечислений, но не смог объяснить вывод для следующего кода:

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

Это выводит:

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

Теперь, почему он выбрал бы третью "1", первую "2" и "3", а вторую "4"? Это неопределенное поведение, или я упускаю что-то очевидное?

1 ответ

Решение

Это специально задокументировано как недокументированное поведение.

Возможно, что-то в том, как написан код, будет заканчиваться тем, что каждый раз будет выбираться одно и то же, но документация Enum.ToString гласит:

Если несколько членов перечисления имеют одинаковое базовое значение, и вы пытаетесь получить строковое представление имени члена перечисления на основе его базового значения, ваш код не должен делать никаких предположений о том, какое имя метод возвратит.

(мой акцент)

Как упоминалось в комментарии, другая среда выполнения.NET может возвращать разные значения, но вся проблема с недокументированным поведением заключается в том, что она подвержена изменениям без веской (казалось бы) причины. Он может меняться в зависимости от погоды, времени, настроения программиста или даже в виде исправления для среды выполнения.NET. Вы не можете полагаться на недокументированное поведение.

Обратите внимание, что в вашем примере ToString это именно то, что вы хотите посмотреть, так как вы печатаете значение, которое, в свою очередь, преобразует его в строку.

Если вы попытаетесь сделать сравнение, все значения перечисления с одинаковым базовым числовым значением эквивалентны, и вы не сможете определить, какое из них вы сохранили в переменной.

Другими словами, если вы делаете это:

var x = en.a;

нет способа потом сделать вывод, что ты написал en.a и не en.b или же en.c поскольку все они сравниваются равными, они имеют одинаковую базовую стоимость. Ну, если не считать создание программы, которая читает собственный источник.

Другие вопросы по тегам