The behavior of FlagsAttribute is probably not what you suspect

Let’s create another enum:

enum Foo
{
    A,
    B,
    C,
    D
}

You add the FlagsAttribute:

[FlagsAttribute]
enum Foo
{
    A,
    B,
    C,
    D
}

Meaning you want to use the Enum as a Flag, so you can combine them. For example:

Foo foo = Foo.B | Foo.C | Foo.D;

Later, you pass this value on, and you want to test for the presence of Foo.A:

// foo is the same foo as previous 
var hasA = (foo & Foo.A) == Foo.A;

Console.WriteLine("hasA: {0}", hasA);

You think that hasA is false. Is it? It’s not:

Does foo include Foo.A?
Does foo include Foo.A?

How come? Applying the FlagsAttribute doesn’t DO anything with the generated constants for your enum members.

As per the documentation you still need to do it yourself:

Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap.

So we update our enum:

[FlagsAttribute]
enum Foo
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}

and then we test our code again:

Foo foo = Foo.B | Foo.C | Foo.D;
var hasA = (foo & Foo.A) == Foo.A;

Console.WriteLine("hasA: {0}", hasA);

And the result is:

Does foo include Foo.A? It does!
Does foo include Foo.A? It does!

Success!

Hope you have a good one,

-Kristof

PS: please not that I should have added a None enum member, as per the documentation:

Use None as the name of the flag enumerated constant whose value is zero. You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero.

  • Useful post.

    I only want to add that there is an Enum method that allows you to test if an enum value contains a flag (since .NET 4):

    Enum.HasFlag
    http://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.100).aspx

    So, instead of do this:
    var hasA = (foo & Foo.A) == Foo.A;

    You can do this:

    var hasA = foo.HasFlag(Foo.A);

  • FilipGoris

    Yo Homie, …

    I noticed you have a HTTP 500 on your blog. Got a hit to your site when googling Powershell & Symbolic links today. The article returns 500 as well as 4 other in the Powershell category.

    Hth,
    flip