Я просто обнаружил тонкую ошибку, где у меня было перечисление с двумя именами, unintentially совместно использующими то же числовое значение (в этом случае red=10 и crimson=10). Я немного удивлен, что это не синтаксическая ошибка.
public enum Colour
{
Red=10,
Blue=11,
Green=12,
Crimson=10
}
// Debug.Write(Colour.Red==Colour.Crimson) outputs True
Есть ли какая-либо причина реального мира, почему это поведение могло бы быть полезным или действительно думает, что должна быть синтаксическая ошибка?
public enum Colour
{
Red=10,
Rouge=10,
Blue=11,
Bleu=11,
Green=12,
Vert=12,
Black=13,
Noir=13
}
Конечно, есть, хотя, возможно, это не слишком распространено. Если есть сущность/значение, которое обычно известно под двумя разными именами, то это хорошая причина.
Сценарий, который вы представили, возможно, один из таких случаев. Еще лучший вариант, прямо из BCL, это System.Windows.Forms.MessageBoxIcon
enum; члены Stop
, Error
и Hand
имеют одно и то же описание и, более того, одно и то же значение. Звездочка
и Информация
также идентичны, как подсказывают комментарии:
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.
Надеюсь, это должно дать вам представление о подходящих сценариях (ваш собственный, вероятно, один из них).
Использование по именованному значению вместо фактического значения является корневым. Предположим, у вас есть французский, английский и т. Д. С одинаковым значением. Для меня это корень перечисления.
Это не синтаксическая ошибка. Все, что делает enum
, - это перечисление серии констант в строго типизированном виде.
Таким образом, если разработчик ошибается (как в вашем примере), то, с точки зрения CLR, это вполне допустимый случай. CLR предполагает, что разработчик знает, что он делает, и почему он решил так поступить.
Что касается реальных случаев, я не могу придумать их на скорую руку, но я уверен, что, вероятно, есть случаи, когда это было бы полезно.
Enum - это перечисление постоянных переменных, и вы можете иметь два элемента с одинаковым значением, я думаю, нет причин для синтаксической ошибки, однако это вызовет ошибку компиляции в этом коде
switch(c)
{
Colour.Red:
break;
Colour.Crimson:
break;
...
}
Я видел, что эта возможность иногда используется для значения "по умолчанию":
public enum Scope
{
Transient,
Singleton,
Default=Transient
}
Но обратите внимание, это только сахар для пользователя вашего перечисления. То, что оно называется Default, не означает, что оно является начальным значением.
Несколько членов перечисления могут иметь одно и то же связанное значение. В примере
enum Color
{
Red,
Green,
Blue,
Max = Blue
}
показано перечисление, в котором два члена перечисления - Blue и Max - имеют одинаковое связанное значение.
В этом случае вы можете проверить MyColor == Color.Max, что было бы полезно при некоторых обстоятельствах.
Я видел то же самое в обертке .net TWAIN - она позволяет хранить все коды сообщений TWAIN в одном большом перечислении, но поначалу это немного запутывает ситуацию.
Все в порядке. У вас может быть два значения, которые отличаются с точки зрения пользователя API, но функционально могут рассматриваться как одно и то же значение.
Перечисления используются как константы, и вы определенно можете иметь две константы с одинаковым значением, которые используются в одних и тех же местах. Это может быть из-за стороннего API, из-за обратной совместимости или просто из-за бизнес-правил.
Иногда рекомендуется (хотя не рекомендовано MS для C #! - см. Комментарий Салароса) включать нижнюю и верхнюю границу в ваше перечисление, например
public enum Colour
{
LowBound=10,
Red=10,
Rouge=10,
Blue=11,
Bleu=11,
Green=12,
Vert=12,
Black=13,
Noir=13,
UpperBound=13
}
Для целей проверки / итерации через каждая возможная настройка. Хотя у меня такое чувство, что .Net может предоставить средство для этого :)