题 你可以遍历所有枚举值吗? [重复]


这个问题在这里已有答案:
如何枚举枚举?  14个答案

public enum Foos
{
    A,
    B,
    C
}

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

基本上?

foreach(Foo in Foos)

1124
2018-06-09 20:25


起源


也可以看看 stackoverflow.com/questions/105372/c-how-to-enumerate-an-enum - SteveC


答案:


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

var values = Enum.GetValues(typeof(Foos));

或者键入的版本:

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();

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

public static class EnumUtil {
    public static IEnumerable<T> GetValues<T>() {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }
}

用法:

var values = EnumUtil.GetValues<Foos>();

1601
2018-06-09 20:28



您可以直接转换数组: (T[])Enum.GetValues(typeof(T)) - Şafak Gür
关于@ŞafakGür评论的好处是(1)你不必经过一个额外的迭代器(.Cast<Foos>),和(2)您不需要包装所有值并再次取消装箱。 Şafak的强制转换将保持有效,只要它们不更改返回到其他类型的数组类型(如 object[])。但是我们可以完全确定它们不会因为(a)它会失去性能,(b)已经有数百万个使用Şafak演员的代码行,并且它们都会因运行时异常而中断。 - Jeppe Stig Nielsen
当然,有多少枚举会包含十几个或两个值?我想在大多数情况下,装箱/拆箱是一个可以忽略不计的命中,所以最干净的解决方案是最高优先级。 - Jon Coombs
@JCoombs我发现这个足够干净: public static IReadOnlyList<T> GetValues<T>() { return (T[])Enum.GetValues(typeof(T)); }。但是,在常见用法中,性能差异可以忽略不计。当我已经有一个可迭代(可枚举)对象返回时,我只是不喜欢创建迭代器的想法。 - Şafak Gür
不幸的是,这并没有回答提出的问题。问题是如何循环枚举的值。 SLaks回答了这个问题。 - JAB


foreach(Foos foo in Enum.GetValues(typeof(Foos)))

671
2018-06-09 20:28



这是一个很好的解决方案。通过使用“Foos”而不是“var”,类型推断系统能够使用正确版本的GetValues返回正确的对象类型。太好了! - Robert Patterson
@RobertPatterson使用 Foos 什么都没有神奇的推断。这是一个明确的演员。 - Chiel ten Brinke
@daveD我想人们可以自己编写一个foreach块。 - Sinjai


foreach (EMyEnum val in Enum.GetValues(typeof(EMyEnum)))
{
   Console.WriteLine(val);
}

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


93
2018-06-09 20:28





foreach (Foos foo in Enum.GetValues(typeof(Foos)))
{
    ...
}

46
2018-06-09 20:29





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

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>();
}

26
2018-06-09 20:30



为什么使用LINQ“更正确”?请c.f. You can cast the array directly: (T[])Enum.GetValues(typeof(T)) @SafakGür,这个版本的IMO开销较小。 - Sebastian
让它变得简单GetEnumValues <T>()其中T:Enum - Saboor Awan
@SaboorAwan无法使用System.Enum作为类型参数约束。编译说: Constraint cannot be special class 'Enum' - Carlos Muñoz
是的,这就是为什么我在我的实现中有注释和类型检查的原因;我已经想到了这一点。 :) - Neil Barnwell
快速说明。在C#7.3中,您现在可以使用 Enum (以及 unmanaged 和 delegate)作为通用约束。 - WBuck


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
}

20
2018-06-09 20:32





 Enum.GetValues(typeof(Foos))

6
2018-06-09 20:30





是。使用 GetValues() 方法 System.Enum 类。


5
2018-06-09 20:28