假设我有这样一个enum:

[Flags]
enum Letters
{
     A = 1,
     B = 2,
     C = 4,
     AB = A | B,
     All = A | B | C,
}

为了检查AB是否被设置,我可以这样做:

if((letter & Letters.AB) == Letters.AB)

有没有一种比下面更简单的方法来检查是否设置了一个组合标志常量的任何标志?

if((letter & Letters.A) == Letters.A || (letter & Letters.B) == Letters.B)

例如,可以将&与其他东西交换吗?


当前回答

抱歉,但我将在VB中显示它:)

   <Flags()> Public Enum Cnt As Integer
        None = 0
        One = 1
        Two = 2
        Three = 4
        Four = 8    
    End Enum

    Sub Test()
    Dim CntValue As New Cnt
    CntValue += Cnt.One
    CntValue += Cnt.Three
    Console.WriteLine(CntValue)
    End Sub

CntValue = 5 所以enum包含1 + 4

其他回答

如果你想知道字母AB中是否有字母,你必须使用AND &运算符。喜欢的东西:

if ((letter & Letters.AB) != 0)
{
    // Some flag (A,B or both) is enabled
}
else
{
    // None of them are enabled
}

有两种方法,我可以看到,将工作检查任何位被设置。

阿普罗赫·

if (letter != 0)
{
}

只要你不介意检查所有位,包括未定义的位,这就可以工作!

阿普罗赫·

if ((letter & Letters.All) != 0)
{
}

这只检查定义的位,只要字母。All表示所有可能的位。

对于特定的位(一个或多个集),使用方法B替换字母。所有这些都是你想要检查的(见下文)。

if ((letter & Letters.AB) != 0)
{
}

为了检查AB是否被设置,我可以这样做: if((字母和字母。ab) ==字母。ab) 有没有一种比下面更简单的方法来检查是否设置了一个组合标志常量的任何标志?

这将检查是否设置了A和B,并忽略是否设置了任何其他标志。

if((字母和字母。a) ==字母。||(字母和字母。b) ==字母。b)

这将检查是否设置了A或B,并忽略是否设置了任何其他标志。

这可以简化为:

if(letter & Letters.AB)

这是二进制运算的C;应用到c#应该很简单:

enum {
     A = 1,
     B = 2,
     C = 4,
     AB = A | B,
     All = AB | C,
};

int flags = A|C;

bool anything_and_a = flags & A;

bool only_a = (flags == A);

bool a_and_or_c_and_anything_else = flags & (A|C);

bool both_ac_and_anything_else = (flags & (A|C)) == (A|C);

bool only_a_and_c = (flags == (A|C));

顺便提一下,问题示例中变量的命名是单数字母“letter”,这可能暗示它只代表一个字母;示例代码清楚地表明,它是一组可能的字母,并且允许多个值,因此可以考虑将变量重命名为“letters”。

如果可以使用。net 4或更高版本,请使用HasFlag()方法

例子

letter.HasFlag(Letters.A | Letters.B) // both A and B must be set

一样

letter.HasFlag(Letters.AB)

如果你觉得很烦,你可以这样写一个函数:

public bool IsSet(Letters value, Letters flag)
{
    return (value & flag) == flag;
}

if (IsSet(letter, Letters.A))
{
   // ...
}

// If you want to check if BOTH Letters.A and Letters.B are set:
if (IsSet(letter, Letters.A & Letters.B))
{
   // ...
}

// If you want an OR, I'm afraid you will have to be more verbose:
if (IsSet(letter, Letters.A) || IsSet(letter, Letters.B))
{
   // ...
}