检查是否仅在枚举中设置了这些标志

时间:2012-11-19 02:25:49

标签: c# bitwise-operators flags

我已经创建了一个扩展方法..

public static bool AllFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    bool allSet = true;
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        if (!((enumVal & val) == val)) 
        {
            allSet = false;
            break;
        }
    }

    return allSet;
}

这对于我需要的目的非常有用,但是我现在需要创建一个具有相同签名的方法,该方法仅检查是否仅设置了这些值。

基本上是这样的。

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
}

我能想到这样做的唯一方法是通过获取所有可用的枚举值来检查设置并确认只提供了两个。

有没有其他方法可以使用某种按位操作来解决这个问题?

5 个答案:

答案 0 :(得分:5)

对所有必需的标志执行“或”并与输入进行比较 - 应该相等。与以下类似,使用正确的循环来计算左侧的值:

var onlyTheseFlagsSet = (value[0] | value[1]) == input;

答案 1 :(得分:2)

排他性要求意味着

input = values[0] | values[1] | ... | values[values.Length - 1]

所以,这是你的实现:

return input.ToInt32(null) == values.Aggregate(0, 
       (total, next) => total | next.ToInt32(null));

答案 2 :(得分:1)

这会翻转每个输入值的位。如果仅设置了这些值,则结果值将为零。否则,如果未在input中设置值,则会将位翻转为1,这将使值保持非零。

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        enumVal = enumVal ^ val;                
    }

    return (enumVal == 0);
}

答案 3 :(得分:0)

我是否遗漏了某些内容,或者您​​是否只能将参数T []值相加并检查输入是否等于结果? 如果你只需要那些标志而不需要其他标志,那么输入应该等于这些标志的总和。

答案 4 :(得分:0)

假设您可以将输入转换为枚举:

foreach(MyFlags flag in values)
    if (!input.HasFlag(flag))
        return false;

return true;

是的,我很懒。