如何将枚举与标志组合使用?

6

我有一个包含标志(flags)的枚举。我想声明一个变量,其中包含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)

但这样做有点凌乱 - 我的看法。 有没有更易读的方法来组合标志?


你可以在这里找到关于枚举标志的惊人概述:https://dev59.com/i3VD5IYBdhLWcg3wWKPc#8480 使用[Flags]属性还将为您提供更好的BiomeType.ToString()表示(即Hot,Dry而不是BiomeType.Hot | BiomeType.Dry18)。 - Marcus Mangelsdorf
3个回答

10
简单,使用二进制“或”运算符
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中提供智能感知,这使得使用枚举更加困难。

1
你应该使用 [Flags] 标记枚举,因为这是你所使用的。 - Blorgbeard
1
非常好,回答得很棒! - BradleyDotNET
1
另外需要注意的是,当在枚举中添加[Flags]属性时,.Net命名约定建议您将名称调整为复数形式 - 在这种情况下为BiomeTypes。请参阅http://msdn.microsoft.com/en-us/library/4x252001(v=vs.71).aspx。 - Gjeltema

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

3
使用位或运算符 |。您将获得 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,
}

(有关解释,请参见C#中[Flags]枚举属性的含义是什么?

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