Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Enumerations and Duplicate Values - dangers?

Tags:

c#

enums

.net-2.0

I was wondering about C# Enumerations and what happens with duplicate values. I created the following small program to test things out:

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");
            }

        }
    }
}

Which produces the following output:

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 . . .

This seems to be EXACTLY what I want and expect since I'm constructing something that a version tag will increment every so often, so I want something that I can "assign" to the current version, and even compare to it.

Here's the question though: what's the pitfalls of this approach? Is there one? Is it just bad style (I don't want to end up on thedailywtf)? Is there a lot better way of doing something like this? I'm on .NET 2.0 and do NOT have the option to go to 3.5 or 4.0.

Opinions are welcome.

like image 831
Kevin Anderson Avatar asked Jul 30 '09 17:07

Kevin Anderson


3 Answers

Providing alias enum values can be useful if you have a flags enum. E.g.

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

However, if you read the guidelines for enums in Framework Design Guidelines by Cwalina and Abrams you will find the following advice:

DO NOT use an enum for open sets (such as the operating system version, names of your friends etc.).

and

DO NOT include sentinel values in enums.

Having a current version is a sentinel value.

These guidelines are for framework design and if you simply want to use the enum internally in your application it may not matter if you break these guidelines. However, Microsoft created these guidelines to avoid common pitfalls when other developers have to use your code.

like image 50
Martin Liversage Avatar answered Oct 13 '22 18:10

Martin Liversage


I see nothing wrong with it, and in fact do the same thing on occasion. There are times when a method (especially a native P/Invoke to an APi that has grown over time) may take in the same numerical values, but they mean something different, so I like to have an enumeration value name that describes the usage.

like image 37
ctacke Avatar answered Oct 13 '22 17:10

ctacke


Its not clear what you're trying to achieve, but it doesn't look great to me. Adding another entry to the enum after 'Duplicate' for example will take the value 0 unless you explicitly set the value again.

like image 42
PaulG Avatar answered Oct 13 '22 19:10

PaulG