如何遍历C#中的所有枚举值?

div*_*nci 1359 .net c# enums language-features

这个问题在这里已有答案:
如何在C#中枚举枚举? 26个答案

public enum Foos
{
    A,
    B,
    C
}
Run Code Online (Sandbox Code Playgroud)

有没有办法循环可能的值Foos

基本上?

foreach(Foo in Foos)
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 1931

是的,你可以使用的GetValue???s方法:

var values = Enum.GetValues(typeof(Foos));
Run Code Online (Sandbox Code Playgroud)

或打字版本:

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();
Run Code Online (Sandbox Code Playgroud)

我很久以前就在这样的场合为我的私人图书馆添加了一个辅助函数:

public static class EnumUtil {
    public static IEnumerable<T> GetValues<T>() {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var values = EnumUtil.GetValues<Foos>();
Run Code Online (Sandbox Code Playgroud)

  • 你可以直接转换数组:`(T [])Enum.GetValues(typeof(T))` (149认同)
  • 关于@ŞafakGür评论的好处是(1)你不必经过一个额外的迭代器(`.Cast <Foos>`),以及(2)你不需要打包所有值并取消它们再次.只要它们不改变返回到其他类型的数组类型(如`object []`),Şafak的强制转换将保持有效.但是我们可以完全确定它们不会因为(a)它会失去性能,(b)已经有数百万个使用Şafak演员的代码行,并且它们都会因运行时异常而中断. (43认同)
  • @JCoombs我发现这个足够干净:`public static IReadOnlyList <T> GetValues <T>(){return(T [])Enum.GetValues(typeof(T)); }`.但是,在常见用法中,性能差异可以忽略不计.当我已经有一个可迭代(可枚举)对象返回时,我只是不喜欢创建迭代器的想法. (12认同)
  • 不幸的是,这并没有回答提出的问题.问题是如何循环枚举的值.SLaks回答了这个问题. (8认同)
  • 当然,有多少枚举将包含一打或两个以上的值?我想在大多数情况下,装箱/拆箱的影响微不足道,因此最干净的解决方案是最高优先级。 (4认同)
  • @JAB,我认为它基本上回答了这个问题,只是有点含蓄。我们用“foreach (var v in value)”代替原来的“Foos” (3认同)
  • 我坚持我的评论。如果性能是这样一个问题,您应该缓存结果。我敢打赌,如果你真的多次调用这个函数,它是一个热门路径,在这种情况下你正在做一个查找,通过将结果缓存到一个“HashSet”,你会获得明显更好的性能。“微软不会改变它,因为我们都已经在滥用它”是一个糟糕的借口。https://en.wikipedia.org/wiki/Tragedy_of_the_commons (2认同)
  • 我也许应该使用“负外部性”而不是“公地悲剧”,但例如“公地困境是一种特定的社会困境,在这种困境中,人们的短期自私利益与长期群体利益相冲突,共同利益”。(https://en.wikipedia.org/wiki/Tragedy_of_the_commons#Commons_dilemma) (2认同)

SLa*_*aks 768

foreach(Foos foo in Enum.GetValues(typeof(Foos)))
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案.通过使用"Foos"而不是"var",类型推断系统能够使用正确版本的GetValues返回正确的对象类型.太好了! (5认同)
  • @daveD我想人们可以自己编写一个foreach块. (4认同)
  • @RobertPatterson通过使用`Foos`,没有任何神奇的推断.这是一个明确的演员. (3认同)
  • @RobertPatterson var 于 2019 年在这里工作。 (2认同)

Ini*_*eer 117

foreach (EMyEnum val in Enum.GetValues(typeof(EMyEnum)))
{
   Console.WriteLine(val);
}
Run Code Online (Sandbox Code Playgroud)

感谢Jon Skeet:http://bytes.com/groups/net-c/266447-how-loop-each-items-enum


adr*_*nks 58

foreach (Foos foo in Enum.GetValues(typeof(Foos)))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*ell 34

更新
一段时间后,我看到一条评论让我回到原来的答案,我想我现在会做的不同.这些天我写道:

private static IEnumerable<T> GetEnumValues<T>()
{
    // Can't use type constraints on value types, so have to do check like this
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException("T must be of type System.Enum");
    }

    return Enum.GetValues(typeof(T)).Cast<T>();
}
Run Code Online (Sandbox Code Playgroud)

  • 让它变得简单GetEnumValues <T>()其中T:Enum (8认同)
  • 为什么使用LINQ“更正确”?请参阅`您可以直接转换数组:(T [])Enum.GetValues(typeof(T))`@SafakGür,此版本的IMO开销较小。 (2认同)
  • @SaboorAwan 不能使用 System.Enum 作为类型参数约束。编译器说:`约束不能是特殊类'Enum'` (2认同)
  • 快速说明。在C#7.3中,您现在可以将“枚举”(以及“非托管”和“委托”)用作通用约束。 (2认同)

dbo*_*nes 24

static void Main(string[] args)
{
    foreach (int value in Enum.GetValues(typeof(DaysOfWeek)))
    {
        Console.WriteLine(((DaysOfWeek)value).ToString());
    }

    foreach (string value in Enum.GetNames(typeof(DaysOfWeek)))
    {
        Console.WriteLine(value);
    }
    Console.ReadLine();
}

public enum DaysOfWeek
{
    monday,
    tuesday,
    wednesday
}
Run Code Online (Sandbox Code Playgroud)


Pab*_*ruz 7

是.GetValues()System.Enum课堂上使用方法.