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

这个问题在这里已经有了答案:

  • 在int C中枚举21枚答案
  • 我如何列举一个枚举? 26个答案

  • 这将返回Enum的所有值的IEnumerable<SomeEnum>

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

    如果你希望这是一个List<SomeEnum> ,只需在.Cast<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));

    为什么这样的语法?

    static方法GetValues是在旧的.NET 1.0版本中引入的。 它返回一个运行时类型SomeEnum[]的一维数组。 但是由于它是一个非泛型方法(泛型没有在.NET 2.0之前引入),所以它不能像这样声明它的返回类型(编译时返回类型)。

    .NET数组确实有一种协变性,但因为SomeEnum将是一个值类型 ,并且由于数组类型协方差不适用于值类型,所以甚至不能将返回类型声明为object[]Enum[] 。 (这不同于例如.NET 1.0中GetCustomAttributes重载,它具有编译时返回类型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>() 。 问题在于它使用Array类的非泛型IEnumerable实现。 这应该包括将每个值装箱到System.Object框中,然后使用Cast<>方法将所有这些值再次取消装箱。 幸运的是.Cast<>方法似乎在开始迭代集合之前检查其IEnumerable参数的运行时类型( this参数),因此它毕竟不是那么糟糕。 事实证明.Cast<>允许通过相同的数组实例。

    如果您遵循.ToArray().ToList() ,如下所示:

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

    你有另一个问题:当你调用GetValues然后用.ToList()调用创建一个新的集合( List<> )时,你创建一个新的集合(数组)。 所以这是整个集合的一个(额外)冗余分配来保存这些值。

    链接地址: http://www.djcxy.com/p/91499.html

    上一篇: How do I convert an enum to a list in C#?

    下一篇: foreach on enum with Custom Attributes