10
Apr
2008

Using LINQ to foreach over an enum in C#

I can't be the only person in the world who wants to foreach over the values of an enum otherwise Enum.GetValues(Type enumType) wouldn't exist in the framework. Alas it didn't get any generics love in .NET 2.0 and unhelpfully returns an array.

Thanks to the power of LINQ you can do this:

foreach(CustomerTypes customerType in Enum.GetValues(typeof(CustomerTypes)).Cast<CustomerTypes>())

That is okay, but this is more concise:

foreach(CustomerTypes customerType in Enums.Get<CustomerTypes>())

The tiny class to achieve that is, of course:

using System.Collections.Generic;
using System.Linq;

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

Great.

[)amien

Share with others These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • description
  • StumbleUpon
  • description
  • Reddit
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • Live
  • Technorati
  • e-mail

8 Responses to “Using LINQ to foreach over an enum in C#”


  1. Gravatar 1 Guy Apr 10th, 2008 at 19:04

    Great post and valuable information - bookmarked and will be used in the future. :)

    Question: Is it actually the power of LINQ that you're using? i.e. Are extension methods part of LINQ or are they part of C# 3.0?

  2. Gravatar 2 Damien Guard Apr 10th, 2008 at 19:04

    Good question!

    LINQ uses some specific compiler magic for the select/in/where/order keywords and also has a bunch of classes in the System.Linq namespace.

    To achieve the functionality requires these classes use Extension methods quite extensively. It also takes advantage of Lambda expressions, anonymous types and is demonstrated often using type inference, all C# 3.0 features!

    [)amien

  3. Gravatar 3 Steve Apr 10th, 2008 at 21:04

    Yuck. Equivalent Java code:

    for (CustomerTypes customerType : CustomerTypes.values())

    One of the rare occasions Java is more concise than C#, obviously ;)

  4. Gravatar 4 Richard Apr 12th, 2008 at 07:04

    You can make use of an extension method to make this slightly nicer... but you call the extension against an instance of the enum (naming for the extension needs to be better):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    static class Enums {
    	public static IEnumerable<T> Values<T>(this T en) where T : struct {
    		if (!typeof(T).IsEnum)
    			throw new InvalidOperationException();
    		foreach (var x inEnum.GetValues(typeof(T)).Cast<T>())
    			yield return x;
    	}
    }
    
    enum Test {
    	One,
    	Two,
    	Three
    }
    
    class Program {
    	static void Main(string[] args) {
    		IEnumerable<Test> t = Test.One.Values();
    		foreach (var x in t)
    			Console.WriteLine(x);
    	}
    }
    
  5. Gravatar 5 Damien Guard Apr 12th, 2008 at 09:04

    That's nice! (hope you don't mind me reformatting it). I did consider going with an extension method but my worry was having .Values appear for all classes.

    [)amien

  6. Gravatar 6 Richard Apr 13th, 2008 at 07:04

    > hope you don't mind me reformatting it

    No problem.

    This is the second time I would have liked to write an extension method that extends the target's static methods (rather than instance).

  7. Gravatar 7 Florent Apr 15th, 2008 at 06:04

    Hi guys :)
    I think that "Cast" method is not mandatory... In fact, you can directly cast that Enum.GetValues return into IEnumerable. Because it's a simple array :)
    So you can do like this:
    IEnumerable myEnumerableOfEnum = (IEnuemrable)Enum.GetValues(typeof(T));
    But you can do this too:
    IList myListOfEnum = (IList)Enum.GetValues(typeof(T));
    T[] myArrayOfEnum = (T[])Enum.GetValues(typeof(T));

    I hope this will usefull :)

  8. Gravatar 8 Florent Apr 15th, 2008 at 06:04

    Oups... T argument is missing :)
    You should read as:
    IEnumerable&lgtT&rgt myEnumerableOfEnum = (IEnuemrable&lgtT&rgt)Enum.GetValues(typeof(T));
    and:
    IList&lgtT&rgt myListOfEnum = (IList&lgtT&rgt)Enum.GetValues(typeof(T));

Leave a reply




Feed subscription

Subjects