Array类和Enum.GetValues()的简单形式

时间:2009-09-12 04:29:43

标签: c# .net

我正在使用静态方法

Enum.GetValues(typeof(SomeEnum));

当您需要做的只是枚举值时,此方法很有效,但由于某种原因,它返回一个非常简单的Array类形式。 我试图找到一种简单的方法将其返回值转换为更“正常”的集合类,如常规数组或List<>。

到目前为止,如果我想这样做,我必须通过Enum.GetValues(typeof(SomeEnum))的输出进行枚举;并将它们逐个添加到List<>。

任何想法如何更干净地做到这一点?

答案:

关键是要转换返回结果 -

SomeEnum[] enums = (SomeEnum[]) Enum.GetValues(typeof(SomeEnum));

如果你需要一个List,那么jus将它包装在括号中并ToList它就像这样:

List<SomeEnum> list = ((SomeEnum[]) Enum.GetValues(typeof(SomeEnum))).ToList();

8 个答案:

答案 0 :(得分:8)

如果您使用的是.NET 3.5,还可以使用Cast<T>和ToList扩展方法。

IEnumerable<SomeEnum> enums = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

如果您想

,也可以获得一个列表
List<SomeEnum> list =  Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();

答案 1 :(得分:4)

found here你可以这样做:

SomeEnum[] enums = (SomeEnum[]) Enum.GetValues(typeof(SomeEnum));

如果你需要一个List,最后只需使用.ToList(),如下所示:

List<SomeEnum> list = ((SomeEnum[]) Enum.GetValues(typeof(SomeEnum))).ToList();

或者如果你更喜欢这个:

List<SomeEnum> list2 = new List<SomeEnum>((SomeEnum[]) Enum.GetValues(typeof(SomeEnum)));

答案 2 :(得分:4)

受Jon Skeet的unconstrained-melody的启发,我想出了更多的版本:

public static class Enum<T>
    where T: struct
{
    static Enum()
    {
        Trace.Assert(typeof(T).IsEnum);
        Values = Array.AsReadOnly((T[])Enum.GetValues(typeof(T)));
    }

    public static readonly ReadOnlyCollection<T> Values;
}

和用法:

var values = Enum<BindingFlags>.Values;

好的是这个版本对多个调用的工作速度更快,因为它不会每次都创建新的数组。

答案 3 :(得分:3)

我有brand new library (UnconstrainedMelody)对此有帮助。它可以返回强类型数组或不可变列表中的值:

SomeEnum[] array = Enums<SomeEnum>.GetValuesArray()
IList<SomeEnum> list = Enums<SomeEnum>.GetValues();

它是通用的,并且对类型参数有一个约束,以确保它真正是一个枚举。这在普通的C#中是不可能的,但是库有一些进一步的作用。我更喜欢第二种形式,因为我们缓存了列表 - 事实上它是不可变的意味着我们可以一次又一次地返回相同的引用。

还有各种其他实用工具方法可以更轻松地使用标记枚举等。

享受。

答案 4 :(得分:1)

修订(2009年9月12日〜美国东部时间下午2点20分)

所以,我昨晚在Enum.GetValues返回Array的基础上提出了这个建议,我认为Array实现IEnumerable<T>

  

我相信你可以构建一个   List<T>传递任何IEnumerable<T>   作为构造函数的参数。   所以你应该能够做到这一点:

List<SomeEnum> values = new List<SomeEnum>(Enum.GetValues(typeof(SomeEnum)));

然而,GordonG很快回复了我的回答,表明它没有编译。 (通常我会测试我的答案,但当时我在一台没有任何开发工具的电脑上,并且对我自己感觉非常[不合理]。)

经过一些沮丧和沉重的反省之后,我决定深入解决这个问题(经过一夜好眠)。 根据微软关于Arrayhere的文档,Array 实施IEnumerable<T>,但仅在运行时(所以,不是在编译时 - 因此编译失败)。事后看来,这是有道理的:Enum.GetValues不是通用方法,所以它不能知道预先返回什么样的通用集合。 (至少这是我理解它的方式。)

无论如何,这一切意味着您可以合法地将Array投射到IEnumerable<T>,前提是您的类型正确。所以,最后我可以提出我的最终答案,这与我原来的答案非常相似,但是为了使一切合法化而投入一个简单的演员:

// splitting into two lines just for readability's sake
List<SomeEnum> values;
values = new List<SomeEnum>((IEnumerable<T>) Enum.GetValues(typeof(SomeEnum)));

当然,回想起来,GordonG并没有因为获得List<T>而死定,这意味着他自己对SomeEnum[]投降的答案真的很好。

答案 5 :(得分:1)

这应该有效:

List<MyEnum> enums = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).ToList();

ToList()在您在问题中发布的解决方案中无法使用的原因是您错过了一组围绕转换部分的parens。希望这有帮助!

答案 6 :(得分:0)

针对.NET framework 2.0的更新解决方案(来自'Konstantin Spirin'):

public static class Enum<T> where T : struct
{
    static Enum()
    {
        Trace.Assert(typeof(T).IsEnum);
    }

    public static ReadOnlyCollection<T> Values = new ReadOnlyCollection<T>(((T[])Enum.GetValues(typeof(T))));
}

答案 7 :(得分:-1)

这个怎么样:

    List<SomeEnum> list = new List<SomeEnum>();
    foreach (SomeEnum value in Enum.GetValues (typeof (SomeEnum)))
    {
        if (condition)
            list.Add(value);
    }