C#: How Can We Enumerate An Enum?

Question

How can I enumerate an enum data type in C#?

Say I have this:

    enum PumpkinVariety
    {
        BabyBear,
        FunnyFace,
        HarvestMoon,
        GhostRider,
        BigMax
    }

How can I list this dynamically in any useful way?

Short Answer

If you have a plain vanilla enum, and you don’t have any funky stuff there such as duplicated values, it’s as easy as this:

foreach (PumpkinVariety pv in Enum.GetValues(typeof(PumpkinVariety)))
{
    // do something here
}

If you do have funky stuff going on, that’s another matter…

Long Answer

If you have duplicate values in your enum, the simple enumeration will not work correctly.

For example, if we have this:

    enum PumpkinVariety
    {
        BabyBear = 1, 
        FunnyFace = 1, // duplicate value
        HarvestMoon = 2,
        GhostRider = 3,
        BigMax = 4
    }

And then run this:

            foreach (PumpkinVariety pv in Enum.GetValues(typeof(PumpkinVariety)))
            {
                Console.WriteLine("{0} = {1}", pv.ToString(), (int)pv);
            }

We end up with this:

BabyBear = 1
BabyBear = 1
HarvestMoon = 2
GhostRider = 3
BigMax = 4

Not the kind of code you’d want to see running on a busy air traffic control tower, is it?

Yeah, that looks kinda dodgy.
So are there any workarounds to get this enumeration working?

There are a few. Let’s see…

If we only need to enumerate the names, we can do this:

            foreach (string name in Enum.GetNames(typeof(PumpkinVariety)))
            {
                // do something here
            }

And if we need to enumerate the values separately, we can do this:

            foreach (int value in Enum.GetValues(typeof(PumpkinVariety)))
            {
                // do something here
            }

However, if we have repeated values in there, we cannot rely on converting them back in proper enum items. We’ve seen what that turns into. We can, however, rely on the names because the uniqueness of these is enforced by the compiler.

We can therefore do something like this:

foreach (string name in Enum.GetNames(typeof(PumpkinVariety)))
{
    // get the enum item itself
    PumpkinVariety pv = (PumpkinVariety)Enum.Parse(typeof(PumpkinVariety), name);

    // get the underlying value
    int value = (int)pv;

    // do something with them
    Console.WriteLine("{0} = {1}", name, value);
}

Granted, that call to Enum.Parse() may take a few extra cycles but, then again, who’s got an atomic clock to measure it?


Index: C# Q&A


Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s