Почему перечисление может иметь два разных имени с одинаковым числовым значением? - PullRequest
26 голосов
/ 30 июня 2010

Я только что обнаружил небольшую ошибку, в которой у меня было перечисление с двумя именами, непреднамеренно разделяющими одно и то же числовое значение (в данном случае red = 10 и crimson = 10). Я немного удивлен, что это не синтаксическая ошибка.

public enum Colour
{
    Red=10,
    Blue=11,
    Green=12,
    Crimson=10
}
// Debug.Write(Colour.Red==Colour.Crimson) outputs True

Существует ли какая-либо реальная причина, по которой такое поведение может быть полезным или же оно должно быть синтаксической ошибкой?

Ответы [ 16 ]

38 голосов
/ 30 июня 2010
public enum Colour
{
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13
}
24 голосов
/ 04 октября 2013

Осторожно! Если ваш enum имеет несколько элементов с одинаковым значением, вы можете получить неожиданные результаты при использовании Enum.Parse(). Это будет произвольно возвращать первый элемент, который имеет запрошенное значение. Например, если у вас есть enum Car { Ford = 1, Chevy = 1, Mazda = 1}, то (Car)Enum.Parse(typeof(Car), "1") вернет Car.Ford. Хотя это может быть полезно (я не уверен, почему это так), в большинстве случаев это может привести к путанице (особенно для инженеров, обслуживающих код) или легко упускать из виду при возникновении проблем.

19 голосов
/ 30 июня 2010

Я видел, что эта функция иногда используется для значения по умолчанию:

public enum Scope
{
    Transient,
    Singleton,
    Default=Transient
}

Но обратите внимание, это всего лишь сахар для пользователя вашего перечисления. То, что оно называется По умолчанию , не означает, что оно является начальным значением.

10 голосов
/ 30 июня 2010

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

7 голосов
/ 30 июня 2010

Из спецификации языка c # :

Несколько членов enum могут иметь одинаковое значение. Пример

enum Color 
{
    Red,
    Green,
    Blue,
    Max = Blue
}

показывает перечисление, в котором два члена перечисления - Blue и Max - имеют одинаковое связанное значение.

В этом случае вы можете проверить MyColor == Color.Max, что может быть полезно при некоторых обстоятельствах.

4 голосов
/ 30 июня 2010

Enum - это Перечисление константных переменных, и вы можете иметь два элемента с одинаковым значением, нет причины быть синтаксической ошибкой. Я думаю, однако, это приведет к ошибке компиляции в этом коде

3 голосов
/ 30 июня 2010

Это не синтаксическая ошибка. Все, что делает enum, перечисляет ряд констант строго типизированным способом.

Таким образом, если разработчик ошибается (как в вашем примере) в отношении CLR, это вполне допустимый случай. CLR предполагает, что разработчик знает, что он делает, и почему он решил это сделать.

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

2 голосов
/ 30 июня 2010

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

Представленный вами сценарий, возможно, является одним из таких случаев. Еще лучше, прямо из BCL, является перечисление System.Windows.Forms.MessageBoxIcon; члены Stop, Error и Hand имеют одинаковое описание и одно и то же значение. Asterisk и Information также идентичны, как предлагается в комментариях:

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.

Надеюсь, это даст вам хорошее представление о подходящих сценариях (вероятно, ваши собственные). 1014 *

1 голос
/ 28 декабря 2016

Этот пример покажет, почему это полезно. Когда вы работаете над публичной библиотекой, которая предназначена для публичного использования, может быть полезным присвоение имен одним и тем же вещам.

public enum GestureType
{
Touch = 1,
Tap = 1,
DoubleTouch = 2,
DoubleTap = 2,
Swipe = 3,
Slide = 3,
...
}

Когда разные слова имеют одинаковое значение в некоторых ситуациях, имеет смысл называть их. При анализе он всегда возвращает хорошее значение в этой ситуации.

1 голос
/ 14 января 2014

Это допустимо и позволяет ссылаться на одно и то же значение под разными именами.Осторожно, это хорошо работает в одностороннем порядке.Вы можете получить противоречивые результаты, если конвертируете из int / string в enum или форматируете строки.

Например:

public enum Colour
{
    Red=10,
    Blue=11,
    Green=12,
    Crimson=10
}
Colour myColor = Colour.Crimson;
Console.WriteLine("Crimson is {0}", myColor.ToString());

Вывод:

Crimson is Red
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...