Skip to main content

How to enumerate an enum?


How can you enumerate a enum in C#?



e.g. the following does not compile:




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

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



It gives the compile time error: 'Suit' is a 'type' but is used like a 'variable'



It fails on the Suit keyword, the 2nd one.



Edit: Got rid of Console.WriteLine(), it was confusing people


Source: Tips4allCCNA FINAL EXAM

Comments

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

    ReplyDelete
  2. 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(suit);
    }
    }


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

    ReplyDelete
  3. 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
    }

    ReplyDelete
  4. The .NET compact framework does not support Enum.GetValues. Here's a good workaround from Ideas 2.0: Enum.GetValues in Compact Framework:

    public IEnumerable<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;
    }

    ReplyDelete
  5. 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]);
    }
    }
    }

    ReplyDelete
  6. You wont' get Enmu.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();
    }
    }

    ReplyDelete
  7. public void PrintAllSuits()
    {
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
    Console.WriteLine(suit);
    }
    }

    ReplyDelete
  8. 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>();

    ReplyDelete
  9. it works with

    foreach (string _name in Enum.GetNames(typeof(Suits)) { ... }

    ReplyDelete
  10. I think you can use

    Enum.GetNames(Suit)

    ReplyDelete
  11. > 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 ar = Enum.GetValues(typeof(Suit));
    foreach(Suit temp_suit in ar) Do_Something(temp_suit);


    That's at least a little faster, ja?

    ReplyDelete
  12. You can enumerate enum by Values and By names.
    Here are more details about that.
    Click Here

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.