1719

This question already has an answer here:
How do I enumerate an enum in C#? 26 answers

public enum Foos
{
    A,
    B,
    C
}

Is there a way to loop through the possible values of Foos?

Basically?

foreach(Foo in Foos)
Cœur
  • 37,241
  • 25
  • 195
  • 267
divinci
  • 22,329
  • 11
  • 45
  • 56

8 Answers8

2456

Yes you can use the ‍GetValue‍‍‍s method:

var values = Enum.GetValues(typeof(Foos));

Or the typed version:

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();

I long ago added a helper function to my private library for just such an occasion:

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

Usage:

var values = EnumUtil.GetValues<Foos>();
Evgeni Sergeev
  • 22,495
  • 17
  • 107
  • 124
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 216
    You can cast the array directly: `(T[])Enum.GetValues(typeof(T))` – Şafak Gür Nov 22 '12 at 09:51
  • 51
    The good thing about @ŞafakGür's comment is that (1) you don't have to go through an extra iterator (`.Cast`), and (2) you don't need to box all the values and unbox them again. Şafak's cast will remain valid as long as they don't change the array type returned to some other type (like `object[]`). But we can be completely sure they won't because (a) it would lose performance, (b) there are already millions of codelines using Şafak's cast, and they would all break with a runtime exception. – Jeppe Stig Nielsen Apr 15 '13 at 17:38
  • 6
    Of course, how many enums are going to contain more than a dozen or two values? I imagine that in most cases boxing/unboxing is a negligible hit, so the cleanest solution is the highest priority. – Jon Coombs Mar 24 '14 at 16:58
  • 15
    @JCoombs I find this clean enough: `public static IReadOnlyList GetValues() { return (T[])Enum.GetValues(typeof(T)); }`. But yeah, performance difference is negligible in common usage. I just don't like the idea of creating an iterator when I already have an iterable (enumerable) object to return. – Şafak Gür Jul 31 '14 at 08:33
  • 13
    Unfortunately, this does not answer the question posed. The question was how to loop through the values of an enum. SLaks answered the question. – JAB Sep 10 '14 at 15:22
  • 3
    @JAB, I think it basically answers it, just somewhat implicitly. Instead of the original "Foos" we'd have `foreach (var v in values)` – Jon Coombs Nov 18 '14 at 21:35
  • When I add the cast `(Foos[])`, my code run 1,6 times faster. Try it yourself. I tested an empty foreach with StopWatch. `for (int i = 0; i < 1000000; i++) foreach (Foos f in (Foos[])Enum.GetValues(typeof(Foos))) {}` – marbel82 Jun 09 '17 at 12:20
  • By casting to an array you are depending on an implementation detail that is subject to change. If Microsoft in the future implements it without an array, your code crashes. If performance is such an issue then you should just cache the results. – Mark Sowul Oct 19 '17 at 17:03
  • @MarkSowul Read the third comment. Great Jon Skeet also uses it [(link)](https://stackoverflow.com/a/3922729/2122718). Microsoft will not dare change it. – marbel82 Apr 27 '18 at 17:07
  • 2
    I stand by my comment. If performance is such an issue, you should cache the results. I bet if you actually are calling this function _so many times_ that it's a hot path, it's a situation where you are doing a lookup, and you would get significantly better performance by caching the result to a `HashSet`. "Microsoft won't change it because we're all already misusing it" is a poor excuse. https://en.wikipedia.org/wiki/Tragedy_of_the_commons – Mark Sowul Apr 30 '18 at 16:58
  • If I want to get the enum number values as list or array then how to use the getValues method? – Md Aslam Jun 22 '20 at 06:00
  • @MarkSowul I read the article [Tragedy of the commons](https://en.wikipedia.org/wiki/Tragedy_of_the_commons) and failed to understand how it relates to your comment/the discussion. Would you mind to explain it? – jarmanso7 Jun 30 '21 at 20:12
  • 1
    @jarmanso7 As an example, let's say that Microsoft did want to optimize Enum.GetValues to return something other than an array (maybe they can point to some internal structure to avoid duplicating, or something). Well, the individual users who have acted according to their own self-interest, by depending on implementation details and saying "Microsoft won't change it because of all the people like me who didn't adhere to the API contract", ruins it for everyone else, because now Microsoft can't change it and everyone else can't benefit from the optimizations. – Mark Sowul Jul 01 '21 at 13:42
  • 2
    I perhaps should have used "negative externality" rather than "tragedy of the commons", but e.g. "The commons dilemma is a specific class of social dilemma in which people's short-term selfish interests are at odds with long-term group interests and the common good." (https://en.wikipedia.org/wiki/Tragedy_of_the_commons#Commons_dilemma) – Mark Sowul Jul 01 '21 at 13:46
  • As of C# 7.3, you can (and probably should) constrain the extension method with `where T : Enum` – user1007074 Apr 04 '23 at 14:27
924
foreach(Foos foo in Enum.GetValues(typeof(Foos)))
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
150
foreach (EMyEnum val in Enum.GetValues(typeof(EMyEnum)))
{
   Console.WriteLine(val);
}

Credit to Jon Skeet here: http://bytes.com/groups/net-c/266447-how-loop-each-items-enum

Inisheer
  • 20,376
  • 9
  • 50
  • 82
69
foreach (Foos foo in Enum.GetValues(typeof(Foos)))
{
    ...
}
adrianbanks
  • 81,306
  • 22
  • 176
  • 206
44

UPDATED
Some time on, I see a comment that brings me back to my old answer, and I think I'd do it differently now. These days I'd write:

private static IEnumerable<T> GetEnumValues<T>()
{
    // Can't use type constraints on value types, so have to do check like this
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException("T must be of type System.Enum");
    }

    return Enum.GetValues(typeof(T)).Cast<T>();
}
Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • 2
    Why is using LINQ "more correct"? Please c.f. `You can cast the array directly: (T[])Enum.GetValues(typeof(T))` @SafakGür, this version has less overhead IMO. – Sebastian Sep 22 '13 at 08:24
  • 10
    make it simple GetEnumValues() where T : Enum – Saboor Awan Apr 03 '14 at 10:27
  • 2
    @SaboorAwan is not possible to use System.Enum as a type parameter constraint. Compiler says: `Constraint cannot be special class 'Enum'` – Carlos Muñoz Mar 09 '16 at 17:26
  • Yes that's why I have that comment and type checking thing in my implementation; I'd already thought of that. :) – Neil Barnwell Mar 16 '16 at 21:03
  • 7
    Quick note. In C# 7.3 you can now use `Enum` (as well as `unmanaged` and `delegate`) as generic constraints. – WBuck May 23 '18 at 12:52
39
static void Main(string[] args)
{
    foreach (int value in Enum.GetValues(typeof(DaysOfWeek)))
    {
        Console.WriteLine(((DaysOfWeek)value).ToString());
    }

    foreach (string value in Enum.GetNames(typeof(DaysOfWeek)))
    {
        Console.WriteLine(value);
    }
    Console.ReadLine();
}

public enum DaysOfWeek
{
    monday,
    tuesday,
    wednesday
}
Tshilidzi Mudau
  • 7,373
  • 6
  • 36
  • 49
dbones
  • 4,415
  • 3
  • 36
  • 52
13

Yes. Use GetValues() method in System.Enum class.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • And if you're using .net5, it comes with a generic version out of the box. i.e. no more typeof() and casting required as per most of the above examples. https://stackoverflow.com/a/65103244/227110 – stoj Jul 17 '22 at 05:33
13
 Enum.GetValues(typeof(Foos))
Vasu Balakrishnan
  • 1,751
  • 10
  • 15