如何将枚举与标志组合?

时间:2014-08-18 20:53:07

标签: c# enums

我有一个带标志的枚举。我想声明一个带有n个不同标志的变量。在这种情况下n > 1

public enum BiomeType {
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,

    Dry = 16,
    Moist = 32,
    Wet = 64,
}

好的 - 一个变体是将每个标志转换为一个字节并将结果转换为我的枚举。

BiomeType bType = (BiomeType)((byte)BiomeType.Hot + (byte)BiomeType.Dry)

但这有点凌乱 - imho。 是否有更可读的方式来组合标志?

3 个答案:

答案 0 :(得分:10)

简单,使用binary "or" operator

BiomeType bType = BiomeType.Hot | BiomeType.Dry;

此外,如果值可以这样组合,最好使用Flags属性标记枚举,以表明:

[Flags]
public enum BiomeType {
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,
    Dry = 16,
    Moist = 32,
    Wet = 64,
}

由于多种原因,添加枚举值很糟糕。它可以很容易地产生一个超出定义值的值,即:

BiomeType bType = (BiomeType)((byte)BiomeType.Wet + (byte)BiomeType.Wet);

虽然做出了设计,但此示例的值为128,未映射到已知值。这仍然可以编译和运行,但是您可能没有构建代码来处理定义之外的值,并可能导致未定义的行为。但是,如果使用管道(或“二进制或”)运算符:

BiomeType bType = BiomeType.Wet | BiomeType.Wet;

结果仍然是BiomeType.Wet

此外,在您的问题中使用添加不会在IDE中提供Intellisense,这使得使用枚举变得更加困难。

答案 1 :(得分:4)

[Flags]属性添加到枚举中。然后你可以掩饰它们:

[Flags]
public enum BiomeType
{
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,

    Dry = 16,
    Moist = 32,
    Wet = 64,
}

BiomeType bType = BiomeType.Hot  | BiomeType.Dry;

(实际上你可以在没有flags属性的情况下进行掩码,但为了清楚起见,你应该添加它。)

你甚至可以做这样的事情来组合所有的旗帜:

var allBiomeTypes = ((BiomeType[])Enum.GetValues(typeof(BiomeType))).Aggregate((BiomeType)0, (a, c) => a | c);

答案 2 :(得分:3)

使用| (bitwise or) operator。您可以获得IntelliSense支持。 (其他按位运算符的功能与基础数字类型相同。)

var bType = BiomeType.Hot | BiomeType.Dry;

您还应该使用[Flags]属性作为枚举定义的提示:

[Flags]
public enum BiomeType
{
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,

    Dry = 16,
    Moist = 32,
    Wet = 64,
}

(有关解释,请参阅What does the [Flags] Enum Attribute mean in C#?