如何在跳过某些值时迭代枚举类型?

RJI*_*IGO 14 c# iteration enums

我的问题的关键部分是跳过.我打算使用一个包含大约20个元素的枚举类型.我想迭代这个集合,但每次都需要跳过一个或两个元素.什么跳过是事先知道的.一个类似的例子是由字母表中的所有字母组成的枚举类型,并且在迭代时,我想跳过所有元音.

我应该如何以优雅/高效的方式编写迭代代码?我应该制作一组由元音组成的单独元素吗?我没有代码可以展示,因为我只是在想这个问题.

Oli*_*bes 33

var query = Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Except(new MyEnum[] { MyEnum.A, MyEnum.E });
foreach (MyEnum item in query) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

你需要施放才能获得LINQ的魔力.Except单独不会这样做.


更新:

我有另一个想法.您可以使用定义枚举,FlagsAttribute并将常规值定义为2的幂,使用按位左移位运算符最容易实现<<.从C#7.0开始,您也可以使用二进制文字0b_0000_0000_0010_0000.然后,可以组合现有值以形成新值.

[Flags]
enum MyEnum
{
    None = 0,
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    ...
    X = 1 << 23,
    Y = 1 << 24,
    Z = 1 << 25,
    Vowels = A | E | I | O | U
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以像这样制定查询

IEnumerable<MyEnum> query = Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Where(x => (x & MyEnum.Vowels) == MyEnum.None);
foreach (MyEnum item in query) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

与第一种解决方案相比,优势在于您可以使用单个按位AND运算执行测试.

您最多可以定义32个2的幂.如果需要更多,可以将枚举的基本类型定义为,long并使用最多64个标志值(加上现有标志值的组合).

[Flags]
enum MyEnum : long
{
    ...
}
Run Code Online (Sandbox Code Playgroud)