locked
"Flags" Attribute -- Useless???

    Question

  • Hi everyone,

    I've read all about the FlagsAttribute and it seems hardly useful.

    From the examples I've seen and the ones I've written myself, I can see only one simple case where using the FlagsAttribute is different from not using it: When you print an instance of a the "FlagsAttribute"-decorated enum, the resulting string contains the enum constants whose bits are set, rather than showing the underlying numeric value.

    Have a look at this snippet:

    [Flags]
    enum Fred : short {
     zero, one, two,  four = 4, eight = 8
    }
    
    class C_01 {
      private static void Main() {
       Fred f = (Fred)7;
       Console.WriteLine("f is " + f);
     } // Main()
    } // class C_01
    

    When I run this snippet, I see this output:

    f is one, two, four

    Okay, that's very nice. The string representation of the enum shows me exactly which bits are set. Wonderful. If I eliminate the [Flags] attribute the output changes to the bare numeric value:

    f is 7

    So, my question is, what else does the [Flags] attribute buy me? Is there something I can do with a [Flags]-decorated enum that I couldn't do otherwise? Is the only purpose of the [Flags] attribute to provide a textual description of the bits that are set? If so, it seems like a marginally useful mechanism, at best.

    Monday, July 31, 2006 6:17 PM

Answers

  • Although C# happily allows users to perform bit operations on enums without the FlagsAttribute, Visual Basic does not. So if you are exposing types to other languages, then marking enums with the FlagsAttribute is a good idea; it also makes it clear that the members of the enum are designed to be used together.

    Regards

    David

    Tuesday, August 01, 2006 2:01 PM

All replies

  • Not sure what you are after but if you check MSDN it is quite straight forward what FlagsAttribute does.
    http://msdn2.microsoft.com/en-us/library/system.flagsattribute.aspx

    FlagsAttribute allows you to combine values (bit mask) instead of identifying a single value.

    The MSDN entry clearly demonstrates the difference between enums with and without this attribute.

    Monday, July 31, 2006 10:56 PM
  • Hi,

    The FlagsAttribute is defined in the System namespace. Adorning the enumerator with this attribute will permit us to treat the variables as bit fields. As a bit field, we are permitted to assign bitwise combinations of the values in the enumeration. Without the flag, we technically are only supposed to be able to assign one value from the enumeration at a time.

    Also if you publish it to be used in webservices it will create the contents for you (it will assign 0x01, 0x02, 0x04, 0x08 and so on) without you specifying them.

    Not other useful function I found either.

    Cheers

     

    Monday, July 31, 2006 11:01 PM
  • Although C# happily allows users to perform bit operations on enums without the FlagsAttribute, Visual Basic does not. So if you are exposing types to other languages, then marking enums with the FlagsAttribute is a good idea; it also makes it clear that the members of the enum are designed to be used together.

    Regards

    David

    Tuesday, August 01, 2006 2:01 PM
  • Did you even read my post?

    The MSDN entry does not demonstrate anything other than what I already said -- there is a difference in the textual representation between "FlagsAttribute" enums and non-"FlagsAttribute" enums. That is *all* the MSDN entry illustrates, nothing more.

    You said , "FlagsAttribute allows you to combine values (bit mask) instead of identifying a single value." Yes, this is true, but you can combine values with a enum that is *not* decorated just as easily. Show me something I can do with a FlagsAttribute that I cannot do with a non-FlagsAttribute.

     

    Tuesday, August 01, 2006 2:23 PM
  • Interesting post. I never thought of using Flags but in my current project I can see great use for it. I also guess that Flags allow for a greater interoperability when used in webservices, crossing language and os bounderies.
    Wednesday, August 02, 2006 8:56 PM
  • Create a file a.txt which is archive and read only, put in the appropriate directory. Run the following code. Comment out  the flags attribute and run again. Status words are often stored as sets of flags and the attribute is useful for checking which are set.

     

    using System;

    using System.IO;

    class FlagsAttributeDemo

    {

        [Flags]

        enum CommonAttributes : short

        {

            Archive = 1,

            Hidden = 2,

            ReadOnly = 32,

            Normal = 128

        }

        static void Main()

        {

            string filename = "a.txt";

            CommonAttributes attr;

            attr = (CommonAttributes)File.GetAttributes(filename);

            Console.WriteLine(attr);

        }

    }

     

    Thursday, July 26, 2007 3:59 PM
  • Create a file a.txt which is archive and read only, put in the appropriate directory. Run the following code. Comment out  the flags attribute and run again. Status words are often stored as sets of flags and the attribute is useful for checking which are set.

     

    using System;

    using System.IO;

    class FlagsAttributeDemo

    {

        [Flags]

        enum CommonAttributes : short

        {

            Archive = 1,

            Hidden = 2,

            ReadOnly = 32,

            Normal = 128

        }

        static void Main()

        {

            string filename = "a.txt";

            CommonAttributes attr;

            attr = (CommonAttributes)File.GetAttributes(filename);

            Console.WriteLine(attr);

        }

    }

     

    Thursday, July 26, 2007 4:00 PM
  • How confusing this all is.

    Ok, to summarize how I see it now :

    1. The [Flags] attribute in C# (not VB !) does nothing more than change the string representation of an enum value.
    2. So, the [Flags] attribute in C# does *not* assign unique bit values to the enum's members. You have to do this manually.

    So if you're working in C# only, this [Flags] attribute is hardly relevant.
    However :

    3. The [Flags] attribute becomes meaningfull when *exposing* your enum to another .NET language like VB, where this flag DOES have significant meaning. I assume in VB this attribute will force unique flag values to the enum's members, unlike in C#.

    What is clear to me now is that the C# MSDN documentation is confusing on this as it does not clearly describe the different behaviour of this [Flags] attribute in C# and VB.
    Monday, June 09, 2008 8:40 PM
  • Erik Bongers said:

    How confusing this all is.

    Ok, to summarize how I see it now :

    1. The [Flags] attribute in C# (not VB !) does nothing more than change the string representation of an enum value.
    2. So, the [Flags] attribute in C# does *not* assign unique bit values to the enum's members. You have to do this manually.

    So if you're working in C# only, this [Flags] attribute is hardly relevant.
    However :

    3. The [Flags] attribute becomes meaningfull when *exposing* your enum to another .NET language like VB, where this flag DOES have significant meaning. I assume in VB this attribute will force unique flag values to the enum's members, unlike in C#.

    What is clear to me now is that the C# MSDN documentation is confusing on this as it does not clearly describe the different behaviour of this [Flags] attribute in C# and VB.

    I'm not following what you mean by "change the string representation of an enum value".

    Point 2, yes, C# doesn't automatically assign bit values to the enum members, it just assigned incremented values.  The compiler can't know you didn't intend to do something like this:

    [Flags]  
    public enum Directions {  
      None, // = 0,  
      North, //= 1,  
      East, //= 2,  
      NorthEast, //= 3 //or North|East  
    //...  




    http://www.peterRitchie.com/blog
    Monday, June 09, 2008 9:02 PM