Ответ 1
public enum Colour
{
Red=10,
Rouge=10,
Blue=11,
Bleu=11,
Green=12,
Vert=12,
Black=13,
Noir=13
}
Я только что обнаружил тонкую ошибку, в которой у меня было перечисление с двумя именами, которые неинтересно использовали одно и то же числовое значение (в данном случае красный = 10 и малиновый = 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
}
Я видел, что эта функция иногда используется для значения по умолчанию:
public enum Scope
{
Transient,
Singleton,
Default=Transient
}
Но обратите внимание, это только сахар для пользователя вашего перечисления. Просто потому, что он называется Default, это не означает, что это начальное значение.
Осторожно! Если ваш enum
имеет несколько элементов с одинаковым значением, вы можете получить неожиданные результаты при использовании Enum.Parse()
. Это приведет к произвольному возврату первого элемента с запрошенным значением. Например, если у вас есть enum Car { Ford = 1, Chevy = 1, Mazda = 1}
, то (Car)Enum.Parse(typeof(Car), "1")
вернет Car.Ford
. Хотя это может быть полезно (я не уверен, почему это было бы так), в большинстве ситуаций это, вероятно, будет путать (особенно для инженеров, поддерживающих код) или легко упускать из виду, когда возникают проблемы.
Перечисления используются как константы, и вы определенно можете иметь две константы с одинаковым значением, которые используются в тех же местах. Это может быть так из-за стороннего API, из-за обратной совместимости только из-за бизнес-правил.
Несколько членов перечисления могут использовать одно и то же связанное значение. Пример
enum Color
{
Red,
Green,
Blue,
Max = Blue
}
показывает перечисление, в котором два члена перечисления - синий и Макс - имеют одинаковое значение.
В этом случае вы можете проверить MyColor == Color.Max, который был бы полезен в некоторых обстоятельствах.
Enum - это перечисление постоянных переменных, и вы можете иметь два элемента с одинаковым значением, нет причин для синтаксической ошибки, я думаю, однако это приведет к ошибке компиляции в этом коде
switch(c)
{
Colour.Red:
break;
Colour.Crimson:
break;
...
}
Это не синтаксическая ошибка. Все enum
- это перечисление ряда констант строго типизированным образом.
Таким образом, если разработчик ошибочно (как и в вашем примере), насколько это касается CLR, это совершенно корректный случай. CLR предполагает, что разработчик знает, что он делает, и почему он решил сделать это.
Что касается реальных случаев, я не могу придумать что-либо на мгновение, но я все еще уверен, что, вероятно, есть случаи, когда это было бы полезно.
Конечно, есть, хотя это, возможно, не слишком распространено. Если есть сущность/значение, которое обычно известно под двумя разными именами, то это хорошая причина.
Сценарий, который вы представили, возможно, один из таких случаев. Еще лучше, прямо из 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.
Надеюсь, это должно дать вам хорошее представление о подходящих сценариях (ваш собственный, вероятно, один).
Это хорошо. У вас могут быть два значения, которые отличаются от точки зрения пользователя API, но функционально могут рассматриваться как одно и то же значение.
Использование по именованному значению в отличие от фактического значения - root. Предположим, у вас есть французский, английский и т.д. С одинаковой стоимостью. Это корень перечисления для меня.
Это допустимо и позволяет присваивать одно и то же значение другим именам. Остерегайтесь, что это хорошо работает. Вы можете получить несогласованные результаты, если вы конвертируете из 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
Я видел одно и то же в обертке .net TWAIN - он позволяет хранить все коды сообщений TWAIN в одном большом перечислении, но вначале он немного запутывает.
Иногда рекомендуется (хотя и не рекомендуется 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 может предоставить вам возможность:)
Я думаю, что существует много применений для повторного использования того же числа. Чтобы дать новый пример, скажем, у вас есть система ранжирования, которая обеспечит создание объектов определенного класса (родителя) перед другими классами, которые зависят от него (дети), у вас могут быть дети, которые находятся на одном уровне 'и неважно, какой из них создан первым. В приведенном ниже примере родитель будет создан сначала, потом 1, 2 или 3 ребенка, затем последним будет Child4. Если бы это рассматривалось как древовидная диаграмма, любые предметы с таким же числом были бы "братья и сестры".
public enum ObjectRanks
{
Parent = 0,
Child1 = 1,
Child2 = 1,
Child3 = 1,
Child4 = 2
}
Хотя я вижу вашу точку зрения в том, что это может быть легко сделать по ошибке. В этом случае было бы удобно, если бы визуальная студия имела возможность включить предупреждения, которые позволяли бы ее компилировать, но повышала бы предупреждение, если бы тот же номер использовался дважды.
В этом примере будет показано, почему это полезно. Когда вы работаете в публичной библиотеке, которая посвящена общественному использованию, может быть полезно присвоение имен одинаковым вещам по-разному.
public enum GestureType
{
Touch = 1,
Tap = 1,
DoubleTouch = 2,
DoubleTap = 2,
Swipe = 3,
Slide = 3,
...
}
Когда разные слова имеют одинаковый смысл в некоторых ситуациях, это имеет смысл, чтобы назвать их. При анализе он всегда возвращает хорошее значение в этой ситуации.