Как преобразовать перечисление в список в C#? [дубликат]



этот вопрос уже есть ответ здесь:




  • Как перечислить перечисление в C#?

    26 ответов



есть ли способ, чтобы преобразовать enum в список, который содержит все параметры перечислимого?

968   14  

14 ответов:

это вернет IEnumerable<SomeEnum> из всех значений перечисления.

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

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

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

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

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

короткий ответ, использовать:

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

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

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

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

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

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

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

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

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

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

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

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

если вы будете следовать за ним по .ToArray() или .ToList(), например:

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

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

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

надеюсь, что это помогает

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

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

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

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

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

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

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

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

.. и система поддержки.Метод расширения строки:

/// <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();
}
Language[] result = (Language[])Enum.GetValues(typeof(Language))
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;
}

преобразовать перечисление в список более подробная информация доступна здесь.

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

Если вы хотите 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
}
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;
}

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

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

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

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

Comments

    Ничего не найдено.