683

Is there a way to convert an enum to a list that contains all the enum's options?

abatishchev
  • 92,232
  • 78
  • 284
  • 421
  • 2
    Strongly related questions: [How do I enumerate an enum?](http://stackoverflow.com/questions/105372/), [Can You Loop Through All Enum Values? (duplicate)](http://stackoverflow.com/questions/972307/). – Jeppe Stig Nielsen May 07 '13 at 05:54
  • I think that if you are looking to do this, you might want to think if you really should be using an enum or if you should switch to an object that represents w/e your enum is. – Bryan Rowe Jul 22 '09 at 18:51
  • 1
    Checking this answer may useful too: https://stackoverflow.com/a/12022617/1830909 – QMaster Nov 22 '17 at 16:54

14 Answers14

1186

This will return an IEnumerable<SomeEnum> of all the values of an Enum.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

If you want that to be a List<SomeEnum>, just add .ToList() after .Cast<SomeEnum>().

To use the Cast function on an Array you need to have the System.Linq in your using section.

Chev
  • 54,842
  • 60
  • 203
  • 309
Jake Pearson
  • 24,693
  • 10
  • 69
  • 90
  • nice.. its is working Array arr = (Array) Enum.GetValues(typeof(SomeEnum)).Cast(); Is this right to work this code line? – Red Swan Aug 13 '10 at 09:09
  • 3
    Actually the result of Cast() is an IEnumerable so if you want an array you would have to change your line to: `var array = Enum.GetValues(typeof(SomeEnum)).Cast().ToArray();` – Jake Pearson Aug 13 '10 at 14:14
  • 79
    that's superfluous, and will mean extra copying. `Enum.GetValues` returns an array already, so you just have to do `var values = (SomeEnum[])Enum.GetValues(typeof(SomeEnum))` – thecoop Nov 09 '10 at 02:33
  • 7
    if you wanna just values then do the cast again : `Enum.GetValues(typeof(SomeEnum)).Cast().Cast().ToList()` – Wahid Bitar Jun 14 '11 at 14:18
  • 1
    Awesome. Just realized that the ordering of the list can be specified by the 'value' of the enums. Ex: enum Foo { A = 1, B = 2, D = 4, C = 3, } => Once this is ran thru the GetValue and Cast, then the order is A, B, C, D. Fantastic! – Graham Oct 26 '11 at 13:17
  • 5
    if its an enum of int values... Enum.GetValues(typeof(EnumType)).Cast().ToArray(); – JGilmartin Feb 29 '12 at 13:02
  • How do we fetch a enum value from a list based on enum name string? – Billa May 19 '13 at 13:59
  • 1
    To get the list of names you use the GetNames method of the Enum object the same way as you do for the GetValues. It will return an array of strings containing the names of each element in the Enum. – David Parvin Aug 19 '13 at 21:05
  • @thecoop I highly doubt the compiler wouldn't optimize that away but better safe than sorry I guess – reggaeguitar May 16 '20 at 00:57
117

Much easier way:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();
abatishchev
  • 92,232
  • 78
  • 284
  • 421
Gili
  • 1,227
  • 1
  • 8
  • 2
  • 18
    Why the `ToList()` between Cast and Select? And how is that much easier than the accepted answer? It's identical to it, except you convert to `string` in the end. – CodesInChaos Dec 05 '10 at 11:44
  • 1
    Just compare the amount of code for this very simple operation. Besides this is more a .NETy solution to this problem. Agree on the ToList(). – Gili Dec 08 '10 at 12:29
  • 7
    I think you can just use Enum.GetNames(typeof(SomeEnum)).ToList() now – JasonWilczak Mar 20 '15 at 16:37
  • 1
    @JasonWilczak Yes, and note that they are not equivalent if the enum type defines "synonyms", i.e. multiple named constants for the same underlying value. For example `Enum.GetNames(typeof(System.Net.HttpStatusCode))` will get _all_ the _distinct_ names, whereas the method from the answer will get some strings duplicated (since `v.ToString()` will pick the same string representation for each duplicate underlying integer value). See [`System.Net.HttpStatusCode` enum documentation](https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx). – Jeppe Stig Nielsen Aug 17 '16 at 13:16
  • 2
    Anyone considering this, please note that the performance of ToString() on an enum is terrible, internally it uses reflection. It's 1000x slower (no exaggeration) than a string -> enum lookup table. – Nic Foster Feb 23 '18 at 23:21
92

The short answer is, use:

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))

If you need that for a local variable, it's var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));.

Why is the syntax like this?!

The static method GetValues was introduced back in the old .NET 1.0 days. It returns a one-dimensional array of runtime type SomeEnum[]. But since it's a non-generic method (generics was not introduced until .NET 2.0), it can't declare its return type (compile-time return type) as such.

.NET arrays do have a kind of covariance, but because SomeEnum will be a value type, and because array type covariance does not work with value types, they couldn't even declare the return type as an object[] or Enum[]. (This is different from e.g. this overload of GetCustomAttributes from .NET 1.0 which has compile-time return type object[] but actually returns an array of type SomeAttribute[] where SomeAttribute is necessarily a reference type.)

Because of this, the .NET 1.0 method had to declare its return type as System.Array. But I guarantee you it is a SomeEnum[].

Everytime you call GetValues again with the same enum type, it will have to allocate a new array and copy the values into the new array. That's because arrays might be written to (modified) by the "consumer" of the method, so they have to make a new array to be sure the values are unchanged. .NET 1.0 didn't have good read-only collections.

If you need the list of all values many different places, consider calling GetValues just once and cache the result in read-only wrapper, for example like this:

public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
    = Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));

Then you can use AllSomeEnumValues many times, and the same collection can be safely reused.

Why is it bad to use .Cast<SomeEnum>()?

A lot of other answers use .Cast<SomeEnum>(). The problem with this is that it uses the non-generic IEnumerable implementation of the Array class. This should have involved boxing each of the values into an System.Object box, and then using the Cast<> method to unbox all those values again. Luckily the .Cast<> method seems to check the runtime type of its IEnumerable parameter (the this parameter) before it starts iterating through the collection, so it isn't that bad after all. It turns out .Cast<> lets the same array instance through.

If you follow it by .ToArray() or .ToList(), as in:

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this

you have another problem: You create a new collection (array) when you call GetValues and then create yet a new collection (List<>) with the .ToList() call. So that's one (extra) redundant allocation of an entire collection to hold the values.

Jeppe Stig Nielsen
  • 54,796
  • 9
  • 96
  • 154
  • 1
    I ended up here looking for a way to get a List<> from my enum, not an Array. If you only want to loop through your enum this is great, but the .Cast().ToList() provides you with an IEnumerable collection, which is valuable in some situations. – DaveD Mar 10 '14 at 20:44
  • 2
    @DaveD The expression `(SomeEnum[])Enum.GetValues(typeof(SomeEnum))` is also `IEnumerable` and `IEnumerable`, and it is `IList` and `IList` as well. But if you need to add or remove entries later, so that the length of the list changes, you *can* copy to a `List`, but that is not the most usual need. – Jeppe Stig Nielsen Mar 10 '14 at 21:13
  • 2
    I've always wondered why they don't just add an `Enum.GetValue()`. – Sebastian Zander Sep 26 '17 at 17:08
46

Here is the way I love, using LINQ:

public class EnumModel
{
    public int Value { get; set; }
    public string Name { get; set; }
}

public enum MyEnum
{
    Name1=1,
    Name2=2,
    Name3=3
}

public class Test
{
        List<EnumModel> enums = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => new EnumModel() { Value = (int)c, Name = c.ToString() }).ToList();

        // A list of Names only, does away with the need of EnumModel 
        List<string> MyNames = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => c.ToString()).ToList();

        // A list of Values only, does away with the need of EnumModel 
        List<int> myValues = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => (int)c).ToList();

        // A dictionnary of <string,int>
        Dictionary<string,int> myDic = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).ToDictionary(k => k.ToString(), v => (int)v);
}

Hope it helps

Booster2ooo
  • 1,140
  • 8
  • 11
  • 11
    `((IEnumerable)Enum.GetValues` should be `((IEnumerable)Enum.GetValues` – Steven Anderson Jun 20 '14 at 05:20
  • Thanks @StevenAnderson, I fixed the anwser. – Booster2ooo Aug 18 '17 at 14:44
  • 1
    That's a great example! I like how you show the model, enum and usage. I was a little stuck on what to do until seeing your answer. Thanks! – Rich Oct 09 '17 at 20:52
  • 1
    I was getting a ReSharper warning on this part:((IEnumerable)Enum.GetValues(typeof(MyEnum)) that said 'Suspicious Cast: There is no type in the solution which is inherited from both System.Array and System.Collections.Generic.IEnumerable' To solve this I changed that line to Enum.GetValues(typeof(MyEnum)).Cast() – Rich Oct 10 '17 at 14:16
  • 1
    @Rich, reading the anwser from Jeppe Stig Nielsen, I think to avoid the warning it's better to cast to an array of MyEnum (instead of IEnumerable of Enum) rather than using .Cast(). – Booster2ooo Oct 11 '17 at 06:42
20
List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();
luisetxenike
  • 209
  • 2
  • 2
16

very simple answer

Here is a property I use in one of my applications

public List<string> OperationModes
{
    get
    {
       return Enum.GetNames(typeof(SomeENUM)).ToList();
    }
}
Tshilidzi Mudau
  • 5,472
  • 6
  • 32
  • 44
Tyler
  • 954
  • 1
  • 8
  • 12
6

I've always used to get a list of enum values like this:

Array list = Enum.GetValues(typeof (SomeEnum));
Claudiu Constantin
  • 1,825
  • 24
  • 36
5
Language[] result = (Language[])Enum.GetValues(typeof(Language))
nawfal
  • 62,042
  • 48
  • 302
  • 339
Shyam sundar shah
  • 2,284
  • 1
  • 21
  • 35
5

Here for usefulness... some code for getting the values into a list, which converts the enum into readable form for the text

public class KeyValuePair
  {
    public string Key { get; set; }

    public string Name { get; set; }

    public int Value { get; set; }

    public static List<KeyValuePair> ListFrom<T>()
    {
      var array = (T[])(Enum.GetValues(typeof(T)).Cast<T>());
      return array
        .Select(a => new KeyValuePair
          {
            Key = a.ToString(),
            Name = a.ToString().SplitCapitalizedWords(),
            Value = Convert.ToInt32(a)
          })
          .OrderBy(kvp => kvp.Name)
         .ToList();
    }
  }

.. and the supporting System.String extension method:

/// <summary>
/// Split a string on each occurrence of a capital (assumed to be a word)
/// e.g. MyBigToe returns "My Big Toe"
/// </summary>
public static string SplitCapitalizedWords(this string source)
{
  if (String.IsNullOrEmpty(source)) return String.Empty;
  var newText = new StringBuilder(source.Length * 2);
  newText.Append(source[0]);
  for (int i = 1; i < source.Length; i++)
  {
    if (char.IsUpper(source[i]))
      newText.Append(' ');
    newText.Append(source[i]);
  }
  return newText.ToString();
}
BrotherOdin
  • 112
  • 8
jenson-button-event
  • 15,947
  • 8
  • 73
  • 144
  • When you say `(T[])(Enum.GetValues(typeof(T)).Cast())`, looking carefully at the parentheses, we see that you actually cast the return value of `Cast` to a `T[]`. That's quite confusing (and maybe surprising it will even work). Skip the `Cast` call. See my new answer for details. – Jeppe Stig Nielsen May 06 '13 at 19:47
4
private List<SimpleLogType> GetLogType()
{
  List<SimpleLogType> logList = new List<SimpleLogType>();
  SimpleLogType internalLogType;
  foreach (var logtype in Enum.GetValues(typeof(Log)))
  {
    internalLogType = new SimpleLogType();
    internalLogType.Id = (int) (Log) Enum.Parse(typeof (Log), logtype.ToString(), true);
    internalLogType.Name = (Log)Enum.Parse(typeof(Log), logtype.ToString(), true);
    logList.Add(internalLogType);
  }
  return logList;
}

in top Code , Log is a Enum and SimpleLogType is a structure for logs .

public enum Log
{
  None = 0,
  Info = 1,
  Warning = 8,
  Error = 3
}
  • Your `foreach` variable has compile-time type `object` (written as `var`), but it really is a `Log` value (runtime type). There's no need to call `ToString` and then `Enum.Parse`. Start your `foreach` with this instead: `foreach (var logtype in (Log[])Enum.GetValues(typeof(Log))) { ... }` – Jeppe Stig Nielsen May 06 '13 at 20:01
4
public class NameValue
{
    public string Name { get; set; }
    public object Value { get; set; }
}

public class NameValue
{
    public string Name { get; set; }
    public object Value { get; set; }
}

public static List<NameValue> EnumToList<T>()
{
    var array = (T[])(Enum.GetValues(typeof(T)).Cast<T>()); 
    var array2 = Enum.GetNames(typeof(T)).ToArray<string>(); 
    List<NameValue> lst = null;
    for (int i = 0; i < array.Length; i++)
    {
        if (lst == null)
            lst = new List<NameValue>();
        string name = array2[i];
        T value = array[i];
        lst.Add(new NameValue { Name = name, Value = value });
    }
    return lst;
}

Convert Enum To a list more information available here.

Tshilidzi Mudau
  • 5,472
  • 6
  • 32
  • 44
Kiarash
  • 1,351
  • 2
  • 12
  • 20
1
/// <summary>
/// Method return a read-only collection of the names of the constants in specified enum
/// </summary>
/// <returns></returns>
public static ReadOnlyCollection<string> GetNames()
{
    return Enum.GetNames(typeof(T)).Cast<string>().ToList().AsReadOnly();   
}

where T is a type of Enumeration; Add this:

using System.Collections.ObjectModel; 
frigate
  • 11
  • 1
1

If you want Enum int as key and name as value, good if you storing the number to database and it is from Enum!

void Main()
{
     ICollection<EnumValueDto> list = EnumValueDto.ConvertEnumToList<SearchDataType>();

     foreach (var element in list)
     {
        Console.WriteLine(string.Format("Key: {0}; Value: {1}", element.Key, element.Value));
     }

     /* OUTPUT:
        Key: 1; Value: Boolean
        Key: 2; Value: DateTime
        Key: 3; Value: Numeric         
     */
}

public class EnumValueDto
{
    public int Key { get; set; }

    public string Value { get; set; }

    public static ICollection<EnumValueDto> ConvertEnumToList<T>() where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new Exception("Type given T must be an Enum");
        }

        var result = Enum.GetValues(typeof(T))
                         .Cast<T>()
                         .Select(x =>  new EnumValueDto { Key = Convert.ToInt32(x), 
                                       Value = x.ToString(new CultureInfo("en")) })
                         .ToList()
                         .AsReadOnly();

        return result;
    }
}

public enum SearchDataType
{
    Boolean = 1,
    DateTime,
    Numeric
}
xajler
  • 31
  • 1
  • 2
-1

You could use the following generic method:

public static List<T> GetItemsList<T>(this int enums) where T : struct, IConvertible
{
    if (!typeof (T).IsEnum)
    {
        throw new Exception("Type given must be an Enum");
    }

    return (from int item in Enum.GetValues(typeof (T))
            where (enums & item) == item
            select (T) Enum.Parse(typeof (T), item.ToString(new CultureInfo("en")))).ToList();
}
M Reza
  • 13,860
  • 13
  • 53
  • 64
Vitall
  • 1,101
  • 1
  • 12
  • 19
  • 1
    You first get the values, then cast each to `int`, then calls `ToString` with a weird culture on that `int`, then parses the string back to type `T`? Downvoted. – Jeppe Stig Nielsen May 06 '13 at 19:54
  • Yes cast all values to int for check, does enums contains item, when cast to string to parse enum back. This method more useful with BitMask. CultureInfo not reqired. – Vitall May 07 '13 at 04:21
  • your parameters and value does not match – reza akhlaghi Oct 05 '19 at 13:49