views:

6117

answers:

11

I have a flag enum below.

[Flags]
public enum FlagTest
{
    None = 0x0,
    Flag1 = 0x1,
    Flag2 = 0x2,
    Flag3 = 0x4
}

I cannot make the if statement evaluate to true.

FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;

if (testItem == FlagTest.Flag1)
{
    // Do something,
    // however This is never true.
}

How can I make this true?

+1  A: 

For bit operations, you need to use bitwise operators.

This should do the trick:

if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
    // Do something,
    // however This is never true.
}

Edit: Fixed my if check - I slipped back into my C/C++ ways (thanks to Ryan Farley for pointing it out)

17 of 26
+34  A: 
if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
     // Do something
}
Scott Nichols
+3  A: 
if((testItem & FlagTest.Flag1) == FlagTest.Flag1) 
{
...
}
Damian Mehers
+1  A: 

Try this:


if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
    // do something
}
Basically, your code is asking if having both flags set is the same as having one flag set, which is obviously false. The code above will leave only the Flag1 bit set if it is set at all, then compares this result to Flag1.

OwenP
+13  A: 

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.

Keith
+2  A: 

Not sure why:

if(testItem & FlagTest.Flag1)

is getting upmodded. It won't compile as it is missing the check for eqality. FlagTest & FlagTest does not evaluate to true/false and will therefore get a compiler error.

Ryan Farley
+1  A: 

Regarding the edit. You can't make it true. I suggest you wrap what you want into another class (or extension method) to get closer to the syntax you need.

i.e.

public class FlagTestCompare
{
    public static bool Compare(this FlagTest myFlag, FlagTest condition)
    {
         return ((myFlag & condition) == condition);
    }
}
Martin Clarke
+13  A: 

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.

Phil Devaney
Ah, finally something out of the box. This is great, I've been waiting for this relatively simple feature for a long time. Glad they decided to slip it in.
Rob van Groenewoud
+7  A: 

:) For those who have trouble visualizing what is happening with the accepted solution (which is this)

if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
    // do stuff
}

We have (as per the question) test item defined as so

testItem 
 = flag1 | flag2  
 = 001 | 010  
 = 011

Then in the if statement the left hand side of the equals is as so:

(testItem & flag1) 
 = (011 & 001) 
 = 001

And the full if statement (that evaluates to true if flag1 is set in testItem) as so

(testItem & flag1) == flag1
 = (001) == 001
 = true

Hope that makes sense to people :)

Sekhat
+1  A: 

This should be a comment but as I'm a new user it looks like I just can't add comments yet...

public static bool IsSet( this Enum input, Enum matchTo ) 
{ 
    return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0; 
}

Is there a way to be compatible with any kind of enum (because here it won't work if your enum is of type UInt64 or can have negative values)?

A: 

One more advice... Never set to the flag as a value "0". Or your check on this flag alway will be true :)

    [Flags]
    public enum LevelOfDetail
    {
        [EnumMember(Value = "FullInfo")]
        FullInfo=0,
        [EnumMember(Value = "BusinessData")]
        BusinessData=1
}

and later if you check input parameter on FullInfo - you get a fun:

detailLevel =  LevelOfDetail.BusinessData;
bool bPRez = (detailLevel & LevelOfDetail.FullInfo) == LevelOfDetail.FullInfo;
Leonid