Перечисления C # и повторяющиеся значения - опасности? - PullRequest
5 голосов
/ 30 июля 2009

Мне было интересно узнать о C # перечислениях и о том, что происходит с дублирующимися значениями. Я создал следующую небольшую программу для проверки:

namespace ConsoleTest
{

    enum TestEnum
    {
        FirstElement = -1,
        SecondElement,
        ThirdElement,
        Duplicate = FirstElement
    }

    /// <summary>
    /// Summary description for MainConsole.
    /// </summary>
    public class MainConsole
    {
        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public MainConsole()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        /// <summary>
        /// Entry point for the application.
        /// </summary>
        /// <param name="args">Arguments to the application</param>
        public static void Main(string[] args)
        {
            TestEnum first = TestEnum.FirstElement;
            TestEnum second = TestEnum.SecondElement;
            TestEnum duplicate = TestEnum.Duplicate;

            foreach (string str in Enum.GetNames(typeof(TestEnum)))
            {
                Console.WriteLine("Name is: " + str);
            }

            Console.WriteLine("first string is: " + first.ToString());
            Console.WriteLine("value is: " + ((int)first).ToString());
            Console.WriteLine("second string is: " + second.ToString());
            Console.WriteLine("value is: " + ((int)second).ToString());
            Console.WriteLine("duplicate string is: " + duplicate.ToString());
            Console.WriteLine("value is: " + ((int)duplicate).ToString());

            TestEnum fromStr = (TestEnum)Enum.Parse(typeof(TestEnum), "duplicate", true);
            Console.WriteLine("fromstr string is: " + fromStr.ToString());
            Console.WriteLine("value is: " + ((int)fromStr).ToString());
            if (fromStr == TestEnum.Duplicate)
            {
                Console.WriteLine("Duplicate compares the same as FirstElement");
            }
            else
            {
                Console.WriteLine("Duplicate does NOT compare the same as FirstElement");
            }

        }
    }
}

, который производит следующий вывод:

Name is: SecondElement
Name is: ThirdElement 
Name is: FirstElement
Name is: Duplicate
first string is: FirstElement
value is: -1
second string is: SecondElement
value is: 0
duplicate string is: FirstElement
value is: -1
fromstr string is: FirstElement
value is: -1
Duplicate compares the same as FirstElement
Press any key to continue . . .

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

Вот вопрос: в чем подводные камни такого подхода? Есть один? Это просто плохой стиль (я не хочу в конечном итоге на thedailywtf)? Есть ли намного лучший способ сделать что-то подобное? Я нахожусь на .NET 2.0 и не имею возможности перейти на 3.5 или 4.0.

Мнения приветствуются.

Ответы [ 3 ]

5 голосов
/ 30 июля 2009

Предоставление значений перечисления псевдонимов может быть полезно, если у вас есть перечисление флагов. Э.Г.

[Flags]
enum Rows {
  Even = 0x01,
  Odd = = 0x02,
  All = Even | Odd
}

Однако, если вы прочтете рекомендации по перечислениям в Руководство по проектированию структуры от Cwalina и Abrams, вы найдете следующий совет:

НЕ используйте enum для открытых наборов (таких как версия операционной системы, имена ваших друзей и т. Д.).

и

НЕ включать значения часовых в перечислениях.

Имеющая текущая версия является значением дозорного.

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

3 голосов
/ 30 июля 2009

Я не вижу в этом ничего плохого, и иногда делаю то же самое. Есть моменты, когда метод (особенно собственный P / Invoke для APi, который вырос со временем) может принимать те же числовые значения, но они означают что-то другое, поэтому мне нравится иметь имя значения перечисления, которое описывает использование.

1 голос
/ 30 июля 2009

Непонятно, чего вы пытаетесь достичь, но мне это не выглядит великолепно. Например, добавление другой записи в перечисление после 'Duplicate' примет значение 0, если вы не установите это значение явно.

...