Home How do I enumerate an enum?
Reply: 26

How do I enumerate an enum?

Ian Boyd
1#
Ian Boyd Published in 2008-09-19 20:34:50Z

How can you enumerate an enum in C#?

E.g. the following code does not compile:

public enum Suit 
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod() 
{
    foreach (Suit suit in Suit) 
    {
        DoSomething(suit);
    }
}

And gives the following compile-time error:

'Suit' is a 'type' but is used like a 'variable'

It fails on the Suit keyword, the second one.

BartoszKP
2#
BartoszKP Reply to 2016-03-13 18:49:37Z
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
    // ...
}
bluish
3#
bluish Reply to 2011-07-25 07:46:06Z

I think you can use

Enum.GetNames(Suit)
metalmad
4#
metalmad Reply to 2014-02-10 18:04:36Z

It looks to me like you really want to print out the names of each enum, rather than the values. In which case Enum.GetNames() seems to be the right approach.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (string name in Enum.GetNames(typeof(Suits)))
    {
        System.Console.WriteLine(name);
    }
}

By the way, incrementing the value is not a good way to enumerate the values of an enum. You should do this instead.

I would use Enum.GetValues(typeof(Suit)) instead.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}
Termininja
5#
Termininja Reply to 2017-01-09 20:45:39Z
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}
bob
6#
bob Reply to 2010-12-07 16:53:32Z

I made some extensions for easy enum usage, maybe someone can use it...

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

The enum itself must be decorated with the FlagsAttribute

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}
Ekevoo
7#
Ekevoo Reply to 2017-08-19 03:04:48Z

Some versions of the .NET framework do not support Enum.GetValues. Here's a good workaround from Ideas 2.0: Enum.GetValues in Compact Framework:

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

As with any code that involves reflection, you should take steps to ensure it runs only once and results are cached.

sprinter252
8#
sprinter252 Reply to 2017-10-06 07:20:14Z
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

I've heard vague rumours that this is terifically slow. Anyone know? – Orion Edwards Oct 15 '08 at 1:31 7

I think caching the array would speed it up considerably. It looks like you're getting a new array (through reflection) every time. Rather:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

That's at least a little faster, ja?

nawfal
9#
nawfal Reply to 2014-01-30 04:43:03Z

Just to add my solution, which works in compact framework (3.5) and supports type checking at compile time:

public static List<T> GetEnumValues<T>() where T : new() {
    T valueType = new T();
    return typeof(T).GetFields()
        .Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
        .Distinct()
        .ToList();
}

public static List<String> GetEnumNames<T>() {
    return typeof (T).GetFields()
        .Select(info => info.Name)
        .Distinct()
        .ToList();
}

- If anyone knows how to get rid of the T valueType = new T(), I'd be happy to see a solution.

A call would look like this:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
Chris
10#
Chris Reply to 2016-01-15 14:11:29Z

You won't get Enum.GetValues() in Silverlight.

Original Blog Post by Einar Ingebrigtsen:

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}
Ahmed Salman Tahir
11#
Ahmed Salman Tahir Reply to 2016-03-17 19:41:48Z

I think this is more efficient than other suggestions because GetValues() is not called each time you have a loop. It is also more concise. And you get a compile-time error not a runtime exception if Suit is not an enum.

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop has this completely generic definition:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}
Mickey Perlstein
12#
Mickey Perlstein Reply to 2015-11-18 15:51:19Z

I use ToString() then split and parse the spit array in flags.

[Flags]
public enum ABC {
   a = 1,
   b = 2,
   c = 4
};

public IEnumerable<ABC> Getselected (ABC flags)
{
   var values = flags.ToString().Split(',');
   var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
   return enums;
}

ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
   Console.WriteLine(item.ToString() + " ID=" + (int)item);
}
Ian Boyd
13#
Ian Boyd Reply to 2015-10-02 14:00:04Z

here is a working example of creating select options for a DDL

var resman = ViewModelResources.TimeFrame.ResourceManager;

ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame 
      in Enum.GetValues(typeof(MapOverlayTimeFrames))
      select new SelectListItem
      {
         Value = timeFrame.ToString(),
         Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
      };
nawfal
14#
nawfal Reply to 2013-01-25 00:05:04Z

I do not hold the opinion this is better, or even good, just stating yet another solution.

If enum values range strictly from 0 to n - 1, a generic alternative:

public void EnumerateEnum<T>()
{
    int length = Enum.GetValues(typeof(T)).Length;
    for (var i = 0; i < length; i++)
    {
        var @enum = (T)(object)i;
    }
}

If enum values are contiguous and you can provide the first and last element of the enum, then:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

but that's not strictly enumerating, just looping. The second method is much faster than any other approach though...

sircodesalot
15#
sircodesalot Reply to 2014-07-25 12:12:52Z

Why is no one using Cast<T>?

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

There you go IEnumerable<Suit>.

Darkside
16#
Darkside Reply to 2013-06-15 08:22:46Z

What the hell I'll throw my two pence in, just by combining the top answers I through together a very simple extension

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Clean simple and by @Jeppe-Stig-Nielsen s comment fast.

Termininja
17#
Termininja Reply to 2017-01-09 23:43:50Z

Three ways:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

Not sure why was GetEnumValues introduced on type instance, it isn't very readable at all for me.


Having a helper class like Enum<T> is what is most readable and memorable for me:

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    public static IEnumerable<T> GetValues()
    {
        return (T[])Enum.GetValues(typeof(T));
    }

    public static IEnumerable<string> GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
}

Now you call:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

One can also use sort of caching if performance matters, but I don't expect this to be an issue at all

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    //lazily loaded
    static T[] values;
    static string[] names;

    public static IEnumerable<T> GetValues()
    {
        return values ?? (values = (T[])Enum.GetValues(typeof(T)));
    }

    public static IEnumerable<string> GetNames()
    {
        return names ?? (names = Enum.GetNames(typeof(T)));
    }
}
Peter Mortensen
18#
Peter Mortensen Reply to 2016-01-17 12:11:23Z

If you need speed and type checking at build and run time, this helper method is better than using LINQ to cast each element:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

And you can use it like below:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Of course you can return IEnumerable<T>, but that buys you nothing here.

Peter Mortensen
19#
Peter Mortensen Reply to 2016-01-17 12:12:22Z
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(The current accepted answer has a cast that I don't think is needed (although I may be wrong).)

anar khalilov
20#
anar khalilov Reply to 2015-05-15 11:31:39Z

I know it is a bit messy but if you are fan of one-liners, here is one:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
Massimiliano Kraus
21#
Massimiliano Kraus Reply to 2016-10-25 14:12:37Z

A simple and generic way to convert an enum to something you can interact:

public static Dictionary<int, string> ToList<T>() where T : struct
{
   return ((IEnumerable<T>)Enum
       .GetValues(typeof(T)))
       .ToDictionary(
           item => Convert.ToInt32(item),
           item => item.ToString());
}

And then:

var enums = EnumHelper.ToList<MyEnum>();
Termininja
22#
Termininja Reply to 2017-01-13 07:22:21Z

This question appears in Chapter 10 of "C# Step by Step 2013"

The author uses a double for-loop to iterate through a pair of Enumerators (to create a full deck of cards):

class Pack
{
    public const int NumSuits = 4;
    public const int CardsPerSuit = 13;
    private PlayingCard[,] cardPack;

    public Pack()
    {
        this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
        for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
        {
            for (Value value = Value.Two; value <= Value.Ace; value++)
            {
                cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
            }
        }
    }
}

In this case, Suit and Value are both enumerations:

enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

and PlayingCard is a card object with a defined Suit and Value:

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}
Slappywag
23#
Slappywag Reply to 2015-10-01 10:21:40Z

What if you know the type will be an enum, but you don't know what the exact type is at compile time?

public class EnumHelper
{
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

The method getListOfEnum uses reflection to take any enum type and returns an IEnumerable of all enum values.

Usage:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}
Termininja
24#
Termininja Reply to 2017-01-13 07:12:47Z

There are two ways to iterate an Enum:

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

The first will give you values in form on a array of object, and the second will give you values in form of array of String.

Use it in foreach loop as below:

foreach(var value in values)
{
    //Do operations here
}
Termininja
25#
Termininja Reply to 2017-01-09 23:39:34Z

Also you can bind to the public static members of the enum directly by using reflection:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));
sprinter252
26#
sprinter252 Reply to 2017-10-06 07:18:22Z

Add method public static IEnumerable<T> GetValues<T>() to your class, like

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

call and pass your enum, now you can iterate through it using foreach

 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }
Emily Chen
27#
Emily Chen Reply to 2018-01-16 20:14:54Z

enum types are called "enumeration types" not because they are containers that "enumerate" values (which they aren't), but because they are defined by enumerating the possible values for a variable of that type.

(Actually, that's a bit more complicated than that - enum types are considered to have an "underlying" integer type, which means each enum value corresponds to an integer value (this is typically implicit, but can be manually specified). C# was designed in a way so that you could stuff any integer of that type into the enum variable, even if it isn't a "named" value.)

The System.Enum.GetNames method can be used to retrieve an array of strings which are the names of the enum values, as the name suggests.

EDIT: Should have suggested the System.Enum.GetValues method instead. Oops.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.332755 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO