Как преобразовать перечисление в список в С#?

Есть ли способ конвертировать enum в список, содержащий все параметры перечисления?

Ответ 1

Это вернет IEnumerable<SomeEnum> всех значений Enum.

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

Если вы хотите, чтобы это было List<SomeEnum>, просто добавьте .ToList() после .Cast<SomeEnum>().

Чтобы использовать функцию Cast на Array, вам нужно иметь System.Linq в вашем разделе использования.

Ответ 2

Гораздо проще:

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

Ответ 3

Короткий ответ:

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

Если вам нужна эта локальная переменная, она var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));.

Почему синтаксис такой?!

Метод static GetValues был введен еще в старые .NET 1.0 дни. Он возвращает одномерный массив типа времени выполнения SomeEnum[]. Но поскольку это не общий метод (generics не был введен до .NET 2.0), он не может объявить его возвращаемый тип (тип возвращаемого времени компиляции) как таковой.

.NET-массивы имеют своего рода ковариацию, но поскольку SomeEnum будет значением типа, и поскольку ковариация типа массива не работает со значениями типов, они не могут даже объявить возвращаемый тип как object[] или Enum[]. (Это отличается от этой перегрузки GetCustomAttributes от .NET 1.0, у которой есть возвращаемый тип времени компиляции object[], но на самом деле возвращает массив типа SomeAttribute[] где SomeAttribute обязательно является ссылочным типом.)

Из-за этого, метод .NET 1.0 должен был объявить свой возвращаемый тип как System.Array. Но я гарантирую вам, что это SomeEnum[].

Каждый раз, когда вы вызываете GetValues снова с тем же типом перечисления, ему придется выделять новый массив и копировать значения в новый массив. Это потому, что массивы могут быть записаны (изменены) "потребителем" метода, поэтому они должны сделать новый массив, чтобы убедиться, что значения не изменяются..NET 1.0 не имел хороших коллекций только для чтения.

Если вам нужен список всех значений в разных местах, рассмотрите возможность вызова GetValues только один раз и кэшируйте результат в оболочке только для чтения, например:

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

Затем вы можете использовать AllSomeEnumValues много раз, и тот же сбор можно безопасно повторно использовать.

Почему плохо использовать .Cast<SomeEnum>()?

Многие другие ответы используют .Cast<SomeEnum>(). Проблема заключается в том, что он использует не-generic IEnumerable реализацию класса Array. Это должно было включать боксирование каждого из значений в поле System.Object, а затем с помощью метода Cast<> снова удалить все эти значения. К счастью, метод .Cast<>, по-видимому, проверяет тип времени выполнения своего параметра IEnumerable (параметр this), прежде чем он начнет выполнять итерацию через коллекцию, поэтому это не так уж плохо. Оказывается, .Cast<> пропускает один и тот же экземпляр массива.

Если вы следуете за ним .ToArray() или .ToList(), как в:

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

у вас возникла другая проблема: при вызове GetValues вы создаете новую коллекцию (массив), а затем создаете новую коллекцию (List<>) с вызовом .ToList(). Так что одно (дополнительное) избыточное выделение всей коллекции для хранения значений.

Ответ 4

Вот как я люблю, используя 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);
}

Надеюсь, поможет

Ответ 5

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

Ответ 6

очень простой ответ

Вот свойство, которое я использую в одном из моих приложений

public List<string> OperationModes
{
    get
    {
       return Enum.GetNames(typeof(SomeENUM)).ToList();
    }
}

Ответ 7

Здесь для полезности... некоторый код для получения значений в списке, который преобразует перечисление в читаемую форму для текста

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

.. и поддерживающий метод расширения System.String:

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

Ответ 8

Я всегда использовал список значений enum, подобных этому:

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

Ответ 9

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

Ответ 10

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

Преобразование Enum В список более доступной информации здесь.

Ответ 11

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

где T - тип перечисления; Добавьте это:

using System.Collections.ObjectModel; 

Ответ 12

Если вы хотите, чтобы Enum int был как ключ и имя как значение, хорошо, если вы храните номер в базе данных и это от 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
}

Ответ 13

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

в верхнем коде, журнал - это перечисление, а SimpleLogType - это структура для журналов.

public enum Log
{
  None = 0,
  Info = 1,
  Warning = 8,
  Error = 3
}

Ответ 14

Вы можете использовать следующий общий метод:

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