Как решаются неоднозначные значения перечислений в 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
поскольку все они сравниваются равными, они имеют одинаковую базовую стоимость. Ну, если не считать создание программы, которая читает собственный источник.