这将返回一个 Enum 的所有值IEnumerable<SomeEnum>
Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
如果您希望将其作为List<SomeEnum>
,只需在.Cast<SomeEnum>()
.ToList()
即可。
要在数组上使用 Cast 函数,您需要在 using 部分中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<>
这就是整个集合的一个(额外)冗余分配,用于保存值。