Check if exclusively only these flags set in enumeration
Asked Answered
B

5

5

I have created an extension method as such..

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

Which works great for the purposes I needed, however I now have a requirement to create a method with the same signature which checks if only exclusively those values have been set.

Basically something like this.

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

The only way I can think of doing this is by getting all available enumeration values checking which are set and confirming that only the two provided have been.

Is there another way to solve this problem using some sort of bitwise operation?

Bihar answered 19/11, 2012 at 2:25 Comment(4)
Is this a homework?? And why is T constraint to a struct and not an enum??Burn
lol, well that's embarrassing. Nope, just don't have a firm grasp of bitwise operations yet... This is a real requirementBihar
Try constraining it to Enum and see what happens. ;-pBihar
Ah, God. I like to dig in some weird unsupported stuff. The CLI claims enum constraint exist, but the CLR doesn't support it. Anyway, you could do an Enum extension instead, that would constraint to Enum type without the weird stuff.Burn
P
5

Do "or" on all required flags and compare with input - should be equal. Similar to following, with correct loop to compute value on the left:

var onlyTheseFlagsSet = (value[0] | value[1]) == input;
Pye answered 19/11, 2012 at 2:30 Comment(0)
I
2

Exclusivity requirement means that

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

So, here is your implementation:

return input.ToInt32(null) == values.Aggregate(0, 
       (total, next) => total | next.ToInt32(null));
Idea answered 19/11, 2012 at 2:39 Comment(1)
+1. That .ToInt32(null) looks strange, but works nevertheless!Pye
D
1

This flips the bit of each input value. If only those are set, the resulting value will be zero. Otherwise, it will flip bits to 1 if the value is not set in input which will leave the value non-zero.

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);
}
Dowitcher answered 19/11, 2012 at 2:34 Comment(5)
+1. I like | approach, but this one is interesting too. Side note - please avoid shrtng nms f vrbls like itm instead of item.Pye
I like the | approach more too. Agreed on variable names, I was just keeping the original author's style.Dowitcher
Side note: just noticed - your code relies on values being mutually exclusive... not necessray true even for values of Enum marked as flags.Pye
@AlexeiLevenkov - Could you please be kind enough to explain that statement further?Bihar
@MaximGershkovich, enum {Hidden=1, Readonly=2, System=4, ReallyHidden=7}. If you try to use [Hidden, ReallyHidden] as list of values bit for 1 will be flipped twice.Pye
M
0

Am I missing something or could you not just sum params T[] values and check if input equals the result?
If you want just those flags and no others, the input should equal the sum of those flags.

Makassar answered 19/11, 2012 at 2:30 Comment(1)
Sum as + may be dangerous since Enum values even for flags types does not have to be mutually exclusive - one need to use or | to combine flags properly.Pye
B
0

Assuming you can convert your input to a enum:

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

return true;

Yes, I'm lazy like that.

Burn answered 19/11, 2012 at 2:38 Comment(1)
I think OP wants to also make sure other flags are not set... waiting for OP's comments...Pye

© 2022 - 2024 — McMap. All rights reserved.