22

Possible Duplicate:
How do I enumerate an enum?

I don't know if it is possible to do what I want to do, but I think why not.

I have example enum:

public enum Animals {
    Cat,
    Dog,
    ...
}

What I want to do is to iterate on this enum. I want it work like that:

foreach( var type in Animals ) {
    Console.WriteLine( type.toString() );
}

and the output will be:

 Cat
 Dog

Is it possible? I don't want to put every item to an array, and then iterate, I want to iterate directly on this enum.

Community
  • 1
  • 1
nirmus
  • 4,913
  • 9
  • 31
  • 50
  • I note you asked "I don't want to put every item to an array, and then iterate", but all the answers offered involve an array with all the values in them. Is this important? – billpg Aug 10 '11 at 17:49
  • The answers are good to me. I didn't want to put to item by hand. If it some language construct for it, it is good solution for me. – nirmus Aug 10 '11 at 19:27

5 Answers5

20

EDIT: Note that throughout this answer I've renamed Animals to Animal. According to .NET conventions, only flags-based enums should have a plural name.

You can use Enum.GetValues():

foreach (var type in (Animal[]) Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(type.toString());
}

As noted in Dan's comment, if you use explicit typing in your foreach loop, you don't need to cast:

foreach (Animal type in Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(type.toString());
}

But now you won't spot errors as early as you could. For example:

foreach (Animal type in Enum.GetValues(typeof(SomeEmptyEnum)) {
    Console.WriteLine(type.toString());
}

Where SomeEmptyEnum is (obviously) an empty enum type. Here GetValues will return an empty array of type SomeEmptyEnum[]. The code above will only check that each member of the returned array is of the right type, so you won't spot the problem. Obviously this is unlikely to happen in real life, but it demonstrates the sort of code smell which leads me to cast the result instead - basically I far prefer dealing with strongly-typed collections.


Alternatively, for a somewhat more typesafe approach, you can use my Unconstrained Melody library:

foreach (var type in Enums.GetValues<Animal>()) {
    Console.WriteLine(type.ToString());
}

Here my Enums.GetValues<T>() returns an IList<T>, which means:

  • There's no need to cast
  • It actually returns an immutable list, so it doesn't need to create a new collection each time, unlike the standard Enum.GetValues()

It's also got a generic constraint forcing T to be an enum type, so you can't accidentally call it with a non-enum type, unlike Enum.GetValues()...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Enum.GetValues is your friend.

Vijay Gill
  • 1,508
  • 1
  • 14
  • 16
1

Use Enum.GetNames() to loop through the names of the members of your enumeration. Use Enum.GetValues() to loop through the values.

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
1

To save some typing in Jon's answer, specify the type explicitly and you won't have to cast:

foreach (Animal a in Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(a);
}

However this would also need additional caution as explained by Jon.

Also note that C# enum names should usually be in singular form (Animal, not Animals), unless they are marked with [Flags] attribute which allows combinations.

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • Have incorporated this into my answer with a bit of extra commentary about why this isn't actually as safe. – Jon Skeet Aug 10 '11 at 12:36
  • No problem - I don't think I'd thought about it before. I think we were editing for the naming convention at the same time, too :) – Jon Skeet Aug 10 '11 at 12:37
1

Try this:

    enum animals
    {
        cat,
        dog,
        fish
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        foreach (string myAnimal in Enum.GetNames(typeof(animals)))
        {
            Debug.WriteLine(myAnimal);
        }
    }

You have to iterate through the Enum.Getnames(typeof(yourEnum)).

Good luck.

Jason James
  • 1,082
  • 1
  • 14
  • 27