Reputation: 4328
I'm trying to evaluate an enum with the FlagsAttribute applied as shown below. The problem is the ridiculous amount of code its taking to ensure the proper if statement runs. I've got four if statements that should only execute if specific combinations of the enum are set but nothing else:
Detecting the existence of the required flags is easy but I also have to ensure that no other flags are set which is a ridiculous amount of code to type and looks like a maintenance nightmare.
[Flags]
public enum AccessModifierType : short
{
Infer = 1,
Public = 2,
Privileged = 4,
Private = 8,
Static = 16
}
Can anyone re-write this if statement to be more concise?
if ((Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Public) == AccessModifierType.Public
&& (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Static) != AccessModifierType.Static
&& (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Privileged) != AccessModifierType.Privileged
&& (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Private) != AccessModifierType.Private){
}
Upvotes: 3
Views: 283
Reputation: 34489
If you use some extensions methods - examples here then you should be able to simplify your code.
AccessModifierType modifier = Model.CurrentContext.CurrentAccessModifierType;
if (modifier.Has(AccessModifierType.Public) &&
modifier.Has(AccessModifierType.Static) &&
modifier.Has(AccessModifierType.Privileged) &&
modifier.Has(AccessModifierType.Private))
{
}
Upvotes: 0
Reputation: 56853
Surely to test if only one flag is set you just test against that flag:
if( Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Private)
...
To see if it equals an exact combination of flags, again, test against that combination:
if( Model.CurrentContext.CurrentAccessModifierType == (AccessModifierType.Private & AccessModifierType.Static))
...
To get your head around this remember that an enum is actually just a number. So if your enum has a value of Private it is just stored as 8, so just test if it equal to 8 (or Private). If it is Private and Static then it is 8 + 16 = 24. So to test if it is both of those then just test if it eqaul to 24 (or Private & Static).
Upvotes: 0
Reputation: 113402
It's not clear how your final sample relates to your original requirements (I get the feeling that Infer
has some special meaning?) but if you're looking for a specific bit combination and nothing else, why not just use an equality test against the exact expected enum value (assembled through bitwise ORs)?
if(myUnknownFlagsEnumValue == (MyEnum.RequiredFlag1 | MyEnum.RequiredFlag2))
{
...
}
Upvotes: 2
Reputation: 1062810
Firstly, comparing to 0 is easier, as is hoisting a value you are using repeatedly:
var access = Model.CurrentContext.CurrentAccessModifierType;
if ((access & AccessModifierType.Public) != 0
&& (access & AccessModifierType.Static) == 0
&& (access & AccessModifierType.Privileged) == 0
&& (access & AccessModifierType.Private) == 0)
{
...
}
If you want to test and no other flag, then just:
if (Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Public)
{
...
}
If you want it to be public but not any of the other three? Then presumably:
if(Model.CurrentContext.CurrentAccessModifierType & (
AccessModifierType.Public | AccessModifierType.Static |
AccessModifierType.Priveleged | AccessModifierType.Private
) == AccessModifierType.Public)
{
...
}
This has the advantage of only being one test (I would also expect the compiler to perform the |
during build, so this is just "ldc
, and
, brtrue
" or "ldc
, and
, brfalse
"
Upvotes: 1