views:

77

answers:

4

What is the difference between the code bellow

' no Flags'
Public Enum MyEnum
  Monday = 1
  Tuesday = 2
  Wednesday = 4
  Thursday = 8
End Enum

and

<Flags()> _ 
Public Enum MyEnum
  Monday = 1
  Tuesday = 2
  Wednesday = 4
  Thursday = 8
End Enum

I do the

Dim days As MyEnum = MyEnum.Monday Or MyEnum.Tuesday Or MyEnum.Wednesday 

If (days And MyEnum.Tuesday) = MyEnum.Tuesday Then
  Console.WriteLine("Tuesday OK") ' here'
Else
  Console.WriteLine("Tuesday NOK")
End If

If (days And MyEnum.Thursday ) = MyEnum.Thursday Then
  Console.WriteLine("Thursday OK")
Else
  Console.WriteLine("Thursday NOK") ' here'
End If

and obtain the same result in both cases(with or without FlagAttribute).

+1  A: 

Basically, it tells the CLR that the values of the enum can be combined. Without this attribute, combining the values would result in an unknown value (but it would still be valid). With the attribute, the combination is correctly interpreted

Without the Flags attributes :

' Gives "Monday, Tuesday" '
Dim s As String = (MyEnum.Monday Or MyEnum.Tuesday).ToString() 

Without the Flags attributes :

' Gives "3" '
Dim s As String = (MyEnum.Monday Or MyEnum.Tuesday).ToString() 
Thomas Levesque
OK, but **practically** (without `ToString()` output difference) does it have any significance?
serhio
It can also affect XML serialization. Serialization of a combination of values will fail if the enum doesn't have the Flags attribute...
Thomas Levesque
@Thomas, can you provide a link for the Serialization issue?
Henk Holterman
I don't have a link, but you can test it very easily... Just try to serialize an unknown combination of unknown values, you will get an exception if the Flags attribute isn't there.
Thomas Levesque
A: 

See Thomas Levesque answer. For example you then can do:

switch (test.day)
{
    case MyEnum.Monday:
        {
            //something when its monday
        }
        break;
    case MyEnum.Tuesday:
        {
            //something when its tuesday
        }
        break;
    case MyEnum.Monday | MyEnum.Tuesday:
        {
            //something when its monday and tuesday (oh the irony)
        }
        break;
}       
PoweRoy
see my comment on the Thomas answer. Your switch will work for what case, with, or without Flags?
serhio
It will work anyway, with or without the attribute
Thomas Levesque
A: 

Also it impacts ToString() output.

Vasiliy Borovyak
why do you say `Also`, do you know other "impacts"?
serhio
Nope. "Also" is redundant of course.
Vasiliy Borovyak
A: 

Serhio,

I can't answer with VB code but flags are very useful in certain circumstances. The example you have demonstrated isn't so good. Image you've got something more like:

enum Format
{
  Bold = 1,
  Italic = 2,
  Underlined = 4
}

Then you could specify the Format to be:

Format format = Format.Bold | Format.Italic;
// Then a check to see if the format is bold or italic should both pass.

Now it is both both and italic (equal to 3). You wouldn't be able to set this without the flags attribute though. It kind of prevents options being mutally exclusive. To do the above without flags you'd have to do:

enum Format
{
  Bold,
  BoldUnderlined,
  BoldItalic,
  BoldUnderlinedItalic,  
  Underlined,  
  Italic,
  ItalicUnderlined
}

No way near as nice.

Ian
You can combine the values even if the enum doesn't have the Flags attribute...
Thomas Levesque
Not according to MSDN you can't http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx. Although I've not yet tried it.
Ian
You **can**, as you can see in my example. Try yourself with your `enum Format` with /without FlagsAttribute. Is sufficient to set values to the power of 2
serhio
Yes, you can set values to the power of 2. But if you set a value to 3 without the flags attribute then that doesn't correspond to a value contained within the enum so its undefined. Whereas with the Flags attribute it should compare to two of the values combined. Check out the MSDN link, in there example where they itterate values.
Ian
serhio