Categories
.net c# enumeration enums loops

How to enumerate an enum

4217

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

2

5119

foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Note: The cast to (Suit[]) is not strictly necessary, but it does make the code 0.5 ns faster.

11

  • 109

    This doesn’t work if you have duplicate values in the enumerator list.

    – Jessy

    Jun 17, 2012 at 3:50

  • 11

    I just want to point out that this, unfortunately won’t work in silverlight, since the silverlight library don’t comprise enum.GetValues. You have to use reflection in this case.

    Oct 17, 2013 at 5:50

  • 166

    @Jessy this does work in case of duplicate situations like enum E {A = 0, B = 0}. Enum.GetValues results in two values being returned, though they are the same. E.A == E.B is true, so there is not distinction. If you want individual names, then you should look for Enum.GetNames.

    – nawfal

    Nov 7, 2013 at 9:25

  • 17

    Then if you have duplicates/synonyms in your enum, and you want the other behavior, you can use Linq’s Distinct extension (since .NET 3.5), so foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.

    Jun 12, 2014 at 8:46

  • 55

    I made the mistake of trying to use var for the type. The compiler will make the variable an Object instead of the enum. List the enum type explicitly.

    – jpmc26

    Jan 8, 2016 at 22:57

798

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

3

  • 3

    VB Syntax here: link

    Sep 9, 2018 at 2:11


  • 1

    I took your version with a small following changes from my side: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). In that case I can iterate array of Suits enum items, not strings.

    – Barabas

    Jun 24, 2019 at 12:57


  • 2

    @Barabas why not just do Suits suit in Enum.GetValues(typeof(Suits)) ?

    Feb 4, 2020 at 22:15

380

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
}

6

  • 18

    A one liner for the first extension method; it’s no more lazy. return Enum.GetValues(typeof(T)).Cast<T>();

    – Leyu

    Jun 22, 2010 at 9:29

  • 2

    Alternatively you could use OfType too: Enum.GetValues(typeof(T)).OfType<T>(). It’s too bad there is not a generic version of GetValues<T>() then it would be even more slick.

    – jpierson

    Jan 10, 2011 at 22:38

  • 3

    Maybe someone could show how to use these extensions? The compiler do not show extension methods on enum EnumExample.

    – Tomas

    Feb 12, 2013 at 8:01


  • 3

    +1 for reusable code: examples – save these extension methods in a library and reference it [Flags]public enum mytypes{name1, name2 }; List<string> myTypeNames = mytypes.GetAllItems();

    – Krishna

    Oct 22, 2013 at 6:55


  • 1

    Starting with C# 7.3 (Visual Studio 2017 ≥ v15.7), one can use where T: Enum

    Jul 27, 2018 at 15:00