How do I convert an enum to a list in C#?

C#.NetEnums

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

Much easier way:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();

Solution 3 - C#

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.


Update: Since .NET 5.0 (from 2020), the above information is obsolete; there is finally a generic method (generics having been introduced with .NET Framework 2.0 from the year 2005), so now you should simply use:

Enum.GetValues<SomeEnum>()

whose return parameter is strongly typed (as SomeEnum[]).

Solution 4 - C#

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

Solution 5 - C#

List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();

Solution 6 - C#

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

Solution 7 - C#

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

Solution 8 - C#

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

Array list = Enum.GetValues(typeof (SomeEnum));

Solution 9 - C#

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.

Solution 10 - C#

Language[] result = (Language[])Enum.GetValues(typeof(Language))

Solution 11 - C#

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
}

Solution 12 - C#

/// <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; 

Solution 13 - C#

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
}

Solution 14 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnewWebView Question on Stackoverflow
Solution 1 - C#Jake PearsonView Answer on Stackoverflow
Solution 2 - C#GiliView Answer on Stackoverflow
Solution 3 - C#Jeppe Stig NielsenView Answer on Stackoverflow
Solution 4 - C#Booster2oooView Answer on Stackoverflow
Solution 5 - C#luisetxenikeView Answer on Stackoverflow
Solution 6 - C#TylerView Answer on Stackoverflow
Solution 7 - C#jenson-button-eventView Answer on Stackoverflow
Solution 8 - C#Claudiu ConstantinView Answer on Stackoverflow
Solution 9 - C#KiarashView Answer on Stackoverflow
Solution 10 - C#Shyam sundar shahView Answer on Stackoverflow
Solution 11 - C#Mohammad EftekhariView Answer on Stackoverflow
Solution 12 - C#frigateView Answer on Stackoverflow
Solution 13 - C#xajlerView Answer on Stackoverflow
Solution 14 - C#VitallView Answer on Stackoverflow