枚举位/标志 实例枚举/迭代/循环遍历

4

完整的枚举迭代

foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
    // ...
}

但是如何迭代位枚举实例?
Suit mySuits = Suit.Hearts | Suit.Diamonds;
// How to now iterate mySuits, which should loop twice instead of four times?
4个回答

6
假设Suit是一个没有重叠值的位枚举类型,那么下面这段代码就足够了:
var availableSuits = Enum.GetValues(typeof(Suit)).Cast<Enum>();
foreach (Suit suit in availableSuits.Where(mySuits.HasFlag)) {
    // ...
}

如果需要快速处理,或者需要忽略复合值或零值,则应该在for循环中检查连续的二次幂,并通过这种方式确定哪些值匹配。


1
你的 Where 对我不起作用,直到我用 Fischermaens 的 item => mySuits.HasFlag(item) 替换它。感谢解决方案!我认为两个答案基本相同,但我会接受你的答案,因为有额外的评论并且是第一个 :) - Cel

2

我的建议:

foreach (var item in Enum.GetValues(typeof(Suit)).Cast<Enum>().Where(item => mySuit.HasFlag(item)))
{
    // Do something
}

1
不完美(拳击),但它能胜任工作...
/// <summary>
/// Return an enumerators of input flag(s)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static IEnumerable<T> GetFlags<T>(this T input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
    {
        if ((int) (object) value != 0) // Just in case somebody has defined an enum with 0.
        {
            if (((Enum) (object) input).HasFlag(value))
                yield return (T) (object) value;
        }
    }
}

使用方法:

    FileAttributes att = FileAttributes.Normal | FileAttributes.Compressed;
    foreach (FileAttributes fa in att.GetFlags())
    {
        ...
    }

-3

枚举只是一种值类型 - 它不可迭代。


我猜你对我的问题进行了负评(尽管我没有给你投负评)?上面的帖子显示它是可迭代的,因此我不确定你假定投负评的原因是什么... - Cel
如果您不熟悉位枚举,它们在某些情况下非常有用(就像所有事物一样),那么这里有一篇文章 - Cel
Frep D-Oronge:你错了,它们可以使用LINQ进行迭代(请参见mquader和我的回答) - Fischermaen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接