尝试在C#枚举中组合Bitflags

时间:2017-07-27 04:17:40

标签: c# enums

public enum EFlagsBmp
{
    None = 0,
    A = (1 << 0),  //1
    B = (1 << 1),  //2
    C = (1 << 2),  //4 
    D = (1 << 3), //8
    E = (1 << 4),  //16
    F = (1 << 5),  //32
    G = (1 << 6),
    H = (1 << 7),
    I = (1 << 8),
    J = (1 << 9),
    K = (1 << 10),
    L = (1 << 11),
    SB1 = (1 << 12),
    SB2 = (1 << 13),
    TR1 = ~(SB1) & ~(SB2),   // BIT12 - 0   BIT13 - 0
    TR2 = (SB1) & ~(SB2),    // BIT12 - 1   BIT13 - 0 
    TR3 = ~(SB1) & (SB2),    // BIT12 - 0   BIT13 - 1
    TR4 = (SB1) | (SB2),     // BIT12 - 1   BIT13 - 1
    VSB = (1 << 18),
}

在这里,我尝试将bitflags(BIT12BIT13)组合如下。

SB1 = (1 << 12),
SB2 = (1 << 13),
TR1 = ~(SB1) & ~(SB2),   // BIT12 - 0   BIT13 - 0
TR2 = (SB1) & ~(SB2),    // BIT12 - 1   BIT13 - 0 
TR3 = ~(SB1) & (SB2),    // BIT12 - 0   BIT13 - 1
TR4 = (SB1) | (SB2),     // BIT12 - 1   BIT13 - 1

我希望能够设置以及回读以下配置

TR1 TR2 TR3 TR4

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您的按位代码不正确。

假设A = 0001 假设B = 0010

A是第一位设置,B是第二位设置

x&amp; 〜A并不代表你的想法。 ~A并不意味着第一位关闭,它意味着1110.所以x&amp;如果设置了3位,则A只会为真,而不仅仅是第一位是关闭的。

如果你想要A没有设置,那就是((x&amp; A)== 0)。或者如果你想要更干净的代码,使用枚举上的[Flags]修饰符然后你得到Enum.HasFlag()。

答案 1 :(得分:0)

你需要考虑你尝试处理标志的事情。标志通常不是独家设置;它们是组合使用的。那么让我们检查一下你的逻辑:

TR1

TR1 = ~(SB1) & ~(SB2),   // BIT12 - 0   BIT13 - 0

结果是:

0011111111111

请注意,这已打开除 SB1SB2之外的每个标志。设置一个标志会影响其他标志。

您真正要做的是检查已设置的标志。为此,您应该使用辅助方法,或使用Enum.HasFlag。它应该被绑定到enum本身,因为它不可能将SB1 & !SB2表示为一组位,同时也将它们视为标志。

因此,您应该:

[Flags]
public enum EFlagsBmp 
{
    ...
}

public static class EFlagsBmpHelper
{
    public static bool TR1(this EFlagsBmp flags)
    {
        return !flags.HasFlag(EFlagsBmp.SB1) && !flags.HasFlag(EFlagsBmp.SB2);
    }
    public static bool TR2(this EFlagsBmp flags)
    {
        return flags.HasFlag(EFlagsBmp.SB1) && !flags.HasFlag(EFlagsBmp.SB2);
    }
    public static bool TR3(this EFlagsBmp flags)
    {
        return !flags.HasFlag(EFlagsBmp.SB1) && flags.HasFlag(EFlagsBmp.SB2);
    }
    public static bool TR4(this EFlagsBmp flags)
    {
        return flags.HasFlag(EFlagsBmp.SB1) && flags.HasFlag(EFlagsBmp.SB2);
    }
}

然后您可以将其用作:

EFlagsBmp.K.TR1()