如何将枚举转换为C#中的列表?

572 .net c# enums

有没有办法将一个转换为enum包含所有枚举选项的列表?

Jak*_*son 990

这将返回IEnumerable<SomeEnum>Enum的所有值中的一个.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
Run Code Online (Sandbox Code Playgroud)

如果你想要的是一个List<SomeEnum>,只需添加.ToList().Cast<SomeEnum>().

要在Array上使用Cast函数,您需要System.Linq在using部分中使用.

  • 这是多余的,意味着额外的复制.`Enum.GetValues`已经返回一个数组,所以你只需要做`var values =(SomeEnum [])Enum.GetValues(typeof(SomeEnum))` (65认同)
  • 如果你想只是值,那么再次进行转换:`Enum.GetValues(typeof(SomeEnum)).Cast <SomeEnum>().Cast <int>().ToList()` (6认同)
  • 如果它是一个int值枚举... Enum.GetValues(typeof(EnumType)).Cast <int>().ToArray(); (4认同)
  • 实际上Cast <T>()的结果是IEnumerable <T>所以如果你想要一个数组,你必须将你的行改为:`var array = Enum.GetValues(typeof(SomeEnum)).Cast <SomeEnum>( ).ToArray();` (3认同)
  • 惊人的。刚刚意识到列表的顺序可以由枚举的“值”指定。例如: enum Foo { A = 1, B = 2, D = 4, C = 3, } =&gt; 一旦通过 GetValue 和 Cast 运行,那么顺序是 A、B、C、D。太棒了! (2认同)
  • 对于 .NET 5.0+:Enum.GetValues&lt;SomeEnum&gt;(); (2认同)

Gil*_*ili 99

更简单的方法:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();
Run Code Online (Sandbox Code Playgroud)

  • 为什么Cast和Select之间的`ToList()`?这比接受的答案更容易吗?它与它完全相同,除了你最后转换为`string`. (13认同)
  • 我想你现在可以使用Enum.GetNames(typeof(SomeEnum)).ToList() (5认同)
  • 只需比较这个非常简单的操作的代码量即可。除此之外,这更多的是针对此问题的 .NETy 解决方案。同意 ToList()。 (2认同)
  • 任何考虑到这一点的人,请注意 ToString() 在枚举上的性能很糟糕,它在内部使用反射。它比字符串 -&gt; 枚举查找表慢 1000 倍(毫不夸张)。 (2认同)

Jep*_*sen 79

简短的回答是,使用:

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))
Run Code Online (Sandbox Code Playgroud)

如果你需要一个局部变量,那就是var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));.

为什么这样的语法?!

static方法GetValues是在旧的.NET 1.0天中引入的.它返回一个运行时类型的一维数组SomeEnum[].但由于它是一种非泛型方法(泛型直到.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)));
Run Code Online (Sandbox Code Playgroud)

然后您可以AllSomeEnumValues多次使用,并且可以安全地重复使用相同的集合.

为什么使用不好.Cast<SomeEnum>()

许多其他答案使用.Cast<SomeEnum>().这个问题是它使用了类的非泛型IEnumerable实现Array.这应该包括将每个值装入一个System.Object框,然后使用该Cast<>方法再次打开所有这些值.幸运的是,该.Cast<>方法似乎在开始迭代集合之前检查其IEnumerable参数(this参数)的运行时类型,所以它毕竟不是那么糟糕.结果是.Cast<>让同一个数组实例通过.

如果你遵循它,.ToArray()或者.ToList()如下:

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this
Run Code Online (Sandbox Code Playgroud)

您还有另一个问题:在调用时创建一个新集合(数组)GetValues,然后List<>使用该.ToList()调用创建一个新集合().这是整个集合的一个(额外)冗余分配来保存值.

  • @DaveD表达式`(SomeEnum [])Enum.GetValues(typeof(SomeEnum))`也是`IEnumerable`和`IEnumerable <SomeEnum>`,它也是`IList`和`IList <SomeEnum>`.但是如果您需要稍后添加或删除条目,以便列表的长度发生变化,您可以*复制到`List <SomeEnum>`,但这不是最常见的需求. (2认同)
  • 我一直想知道为什么他们不只是添加一个 `Enum.GetValue&lt;T&gt;()`。 (2认同)

Boo*_*ooo 30

这是我喜欢的方式,使用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);
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你

  • `((IEnumerable <EnumModel>)Enum.GetValues`应该是`((IEnumerable <MyEnum>)Enum.GetValues` (11认同)

小智 20

List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ler 12

非常简单的答案

这是我在我的一个应用程序中使用的属性

public List<string> OperationModes
{
    get
    {
       return Enum.GetNames(typeof(SomeENUM)).ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)


Kia*_*ash 5

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;
}
Run Code Online (Sandbox Code Playgroud)

将 Enum 转换为列表此处提供更多信息。


jen*_*ent 5

这里有用...用于将值放入列表的一些代码,它将枚举转换为文本的可读形式

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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

..和支持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();
}
Run Code Online (Sandbox Code Playgroud)


Cla*_*tin 5

我总是习惯得到enum像这样的值列表:

Array list = Enum.GetValues(typeof (SomeEnum));
Run Code Online (Sandbox Code Playgroud)

  • 这将为您提供一个数组,而不是List <>. (2认同)

Shy*_*hah 5

Language[] result = (Language[])Enum.GetValues(typeof(Language))
Run Code Online (Sandbox Code Playgroud)