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

This question already has an answer here:

  • Cast int to enum in C# 21 answers
  • How do I iterate over an enum? 26 answers

  • 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.


    更简单的方法:

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

    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 eg 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.

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

    上一篇: 有没有办法遍历所有的枚举值?

    下一篇: 如何将枚举转换为C#中的列表?