假设我有这样一个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)
例如,可以将&与其他东西交换吗?
为了检查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”。
如果你觉得很烦,你可以这样写一个函数:
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))
{
// ...
}
我创建了一个简单的扩展方法,不需要检查Enum类型:
public static bool HasAnyFlag(this Enum value, Enum flags)
{
return
value != null && ((Convert.ToInt32(value) & Convert.ToInt32(flags)) != 0);
}
它也适用于可为空的枚举。标准的HasFlag方法没有,所以我创建了一个扩展来覆盖它。
public static bool HasFlag(this Enum value, Enum flags)
{
int f = Convert.ToInt32(flags);
return
value != null && ((Convert.ToInt32(value) & f) == f);
}
一个简单的测试:
[Flags]
enum Option
{
None = 0x00,
One = 0x01,
Two = 0x02,
Three = One | Two,
Four = 0x04
}
[TestMethod]
public void HasAnyFlag()
{
Option o1 = Option.One;
Assert.AreEqual(true, o1.HasAnyFlag(Option.Three));
Assert.AreEqual(false, o1.HasFlag(Option.Three));
o1 |= Option.Two;
Assert.AreEqual(true, o1.HasAnyFlag(Option.Three));
Assert.AreEqual(true, o1.HasFlag(Option.Three));
}
[TestMethod]
public void HasAnyFlag_NullableEnum()
{
Option? o1 = Option.One;
Assert.AreEqual(true, o1.HasAnyFlag(Option.Three));
Assert.AreEqual(false, o1.HasFlag(Option.Three));
o1 |= Option.Two;
Assert.AreEqual(true, o1.HasAnyFlag(Option.Three));
Assert.AreEqual(true, o1.HasFlag(Option.Three));
}
享受吧!