5

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

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
{
}

我能想到的唯一方法是让所有可用的枚举值检查已设置并确认只有提供的两个已设置。

有没有另一种方法可以使用某种按位运算来解决这个问题?

4

5 回答 5

5

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

var onlyTheseFlagsSet = (value[0] | value[1]) == input;
于 2012-11-19T02:30:31.407 回答
2

排他性要求意味着

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

所以,这是你的实现:

return input.ToInt32(null) == values.Aggregate(0, 
       (total, next) => total | next.ToInt32(null));
于 2012-11-19T02:39:17.390 回答
1

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

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);
}
于 2012-11-19T02:34:28.410 回答
0

我是否遗漏了什么,或者您是否可以不只是对参数 T[] 值求和并检查输入是否等于结果?
如果您只需要这些标志而不需要其他标志,则输入应等于这些标志的总和。

于 2012-11-19T02:30:59.660 回答
0

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

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

return true;

是的,我就是这么懒。

于 2012-11-19T02:38:19.043 回答