FlagsAttribute could've done a bit more

Definition of FlagsAttribute on MSDN sez "Indicates that an enumeration can be treated as a bit field; that is, a set of flags". It further goes on to indicate "Bit fields can be combined using a bitwise OR operation, whereas enumerated constants cannot".

Enums are generally used in situations where mutually exclusive elements are required. However, an enum can be decorated with this FlagsAttribute to indicate that they are bit flags and can also be combined (ORed, ANDed) so that it can also be used in situations where combination of elements are also valid.

When I first encountered this FlagsAttribute I assumed (devs do that a lot :) ) that the values generated for these enums are no longer incremented by 1 but are bit incremented.

 [Flags]enum MyFlagEnum{    None,    First ,    Second,    Third,    Fourth}

So in the case of the above enum I expected that None=0, First=1, Second=2, Third = 4, Fourth=8. Only if this assumption is true we can have bit flags work correctly. Otherwise First|Second will become equal to Third and hence would be indistinguisable from Third.

However, much later I learnt with surprise that this is not true... Even if the attribute is used enum members are just incremented by one. So that Third is 3 and not 4 and Fourth is 4 and not 8.

This can have surprising consequences as demonstrated by the code below

 using System;using System.Collections.Generic;using System.Text;namespace FlagAttribute{    [Flags]    enum MyFlagEnum    {        None,        First ,        Second,        Third,        Fourth    }    class Program    {        static void Main(string[] args)        {            foreach (MyFlagEnum myEnum in 
                       Enum.GetValues(typeof(MyFlagEnum)))            {                Console.WriteLine("{0,-10} => {1}", myEnum, 
                                   myEnum.ToString("D"));            }            Console.WriteLine((MyFlagEnum.First | MyFlagEnum.Second) 
                                                == MyFlagEnum.Third);            Console.WriteLine(MyFlagEnum.First | MyFlagEnum.Second);            Console.WriteLine(MyFlagEnum.Second | MyFlagEnum.Fourth);        }    }}
 None       => 0
First      => 1
Second     => 2
Third      => 3
Fourth     => 4
True<br>Third
Second, Fourth

The problem here is that the value of First|Second is 3 and hence there is no way to distinguish it from MyFlagEnum.Third. However in case of  Second|Fourth the value is 6 and hence the sytem correctly printed it to Second, Fourth.

This can be corrected only by manually giving correct values to the enum members as...

 [Flags]enum MyFlagEnum{    None = 0,    First = 1,    Second = 2,    Third = 4,    Fourth = 8}

So what did we gain from the FlagsAttribute, not much I guess...