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);
}
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
@phil-devaney
Note that except in the simplest of cases, the Enum.HasFlag carries a heavy performance penalty in comparison to writing out the code manually. Consider the following code:
[Flags]
public enum TestFlags
{
One = 1,
Two = 2,
Three = 4,
Four = 8,
Five = 16,
Six = 32,
Seven = 64,
Eight = 128,
Nine = 256,
Ten = 512
}
class Program
{
static void Main(string[] args)
{
TestFlags f = TestFlags.Five; /* or any other enum */
bool result = false;
Stopwatch s = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
result |= f.HasFlag(TestFlags.Three);
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds); // *4793 ms*
s.Restart();
for (int i = 0; i < 10000000; i++)
{
result |= (f & TestFlags.Three) != 0;
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds); // *27 ms*
Console.ReadLine();
}
}
Over 10 million iterations, the HasFlags extension method takes a whopping 4793 ms, compared to the 27 ms for the standard bitwise implementation.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With