I have a flag enum below.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
I cannot make
even without [Flags], you could use something like this
if((testItem & (FlagTest.Flag1 | FlagTest.Flag2 ))!=0){
//..
}
or if you have a Zero value enum
if((testItem & (FlagTest.Flag1 | FlagTest.Flag2 ))!=FlagTest.None){
//..
}
if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
// Do something
}
(testItem & FlagTest.Flag1)
is a bitwise AND operation.
FlagTest.Flag1
is equivalent to 001
with OP's enum. Now let's say testItem
has Flag1 and Flag2 (so it's bitwise 101
):
001
&101
----
001 == FlagTest.Flag1
For those who have trouble visualizing what is happening with the accepted solution (which is this),
if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
// Do stuff.
}
testItem
(as per the question) is defined as,
testItem
= flag1 | flag2
= 001 | 010
= 011
Then, in the if statement, the left hand side of the comparison is,
(testItem & flag1)
= (011 & 001)
= 001
And the full if statement (that evaluates to true if flag1
is set in testItem
),
(testItem & flag1) == flag1
= (001) == 001
= true
In .NET 4 there is a new method Enum.HasFlag. This allows you to write:
if ( testItem.HasFlag( FlagTest.Flag1 ) )
{
// Do Stuff
}
which is much more readable, IMO.
The .NET source indicates that this performs the same logic as the accepted answer:
public Boolean HasFlag(Enum flag) {
if (!this.GetType().IsEquivalentTo(flag.GetType())) {
throw new ArgumentException(
Environment.GetResourceString(
"Argument_EnumTypeDoesNotMatch",
flag.GetType(),
this.GetType()));
}
ulong uFlag = ToUInt64(flag.GetValue());
ulong uThis = ToUInt64(GetValue());
// test predicate
return ((uThis & uFlag) == uFlag);
}
One more piece of advice... Never do the standard binary check with the flag whose value is "0". Your check on this flag will always be true.
[Flags]
public enum LevelOfDetail
{
[EnumMember(Value = "FullInfo")]
FullInfo=0,
[EnumMember(Value = "BusinessData")]
BusinessData=1
}
If you binary check input parameter against FullInfo - you get:
detailLevel = LevelOfDetail.BusinessData;
bool bPRez = (detailLevel & LevelOfDetail.FullInfo) == LevelOfDetail.FullInfo;
bPRez will always be true as ANYTHING & 0 always == 0.
Instead you should simply check that the value of the input is 0:
bool bPRez = (detailLevel == LevelOfDetail.FullInfo);
I set up an extension method to do it: related question.
Basically:
public static bool IsSet( this Enum input, Enum matchTo )
{
return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
}
Then you can do:
FlagTests testItem = FlagTests.Flag1 | FlagTests.Flag2;
if( testItem.IsSet ( FlagTests.Flag1 ) )
//Flag1 is set
Incidentally the convention I use for enums is singular for standard, plural for flags. That way you know from the enum name whether it can hold multiple values.