Подтвердить что ты не робот

Почему для перечисления должно быть два разных имени с одинаковым числовым значением?

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

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

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

4b9b3361

Ответ 1

public enum Colour
{
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13
}

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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

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

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

Ответ 6

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

switch(c)
{
  Colour.Red:
     break;
  Colour.Crimson:
     break;
  ...
}

Ответ 7

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

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

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

Ответ 8

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

Сценарий, который вы представили, возможно, один из таких случаев. Еще лучше, прямо из BCL, является System.Windows.Forms.MessageBoxIcon enum; члены 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.

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

Ответ 9

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

Ответ 10

Использование по именованному значению в отличие от фактического значения - root. Предположим, у вас есть французский, английский и т.д. С одинаковой стоимостью. Это корень перечисления для меня.

Ответ 11

Это допустимо и позволяет присваивать одно и то же значение другим именам. Остерегайтесь, что это хорошо работает. Вы можете получить несогласованные результаты, если вы конвертируете из 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

Ответ 12

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

Ответ 13

Иногда рекомендуется (хотя и не рекомендуется MS для С#! - см. комментарий Salaros), чтобы включить нижнюю и верхнюю границу вашего перечисления, например

public enum Colour
{
    LowBound=10,
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13,
    UpperBound=13
}

В целях проверки/повторения каждой возможной настройки. Хотя у меня такое чувство, что .Net может предоставить вам возможность:)

Ответ 14

Я думаю, что существует много применений для повторного использования того же числа. Чтобы дать новый пример, скажем, у вас есть система ранжирования, которая обеспечит создание объектов определенного класса (родителя) перед другими классами, которые зависят от него (дети), у вас могут быть дети, которые находятся на одном уровне 'и неважно, какой из них создан первым. В приведенном ниже примере родитель будет создан сначала, потом 1, 2 или 3 ребенка, затем последним будет Child4. Если бы это рассматривалось как древовидная диаграмма, любые предметы с таким же числом были бы "братья и сестры".

public enum ObjectRanks
{
    Parent = 0,
    Child1 = 1,
    Child2 = 1,
    Child3 = 1,
    Child4 = 2
}

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

Ответ 15

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

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

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