Use of FlagsAttribute

  • Thread starter Thread starter Randy
  • Start date Start date
R

Randy

I can't seem to find a clear example on how to use the FlagsAttribute. In
my example below shouldn't both message boxes show? Instead no messagebox
displays. I know that .NET will auto-number enum's when omitted.

<Flags()> Public Enum Permission
Read
Write
Delete
Rename
Copy
Move
End Enum

Private p As Permission
p = Permission.Copy And Permission.Read

If p = Permission.Copy Then
MessageBox.Show("Copy")
End If

If p = Permission.Copy And p = Permission.Read Then
MessageBox.Show("Copy & Read")
End If
 
Hi Randy
Randy said:
I can't seem to find a clear example on how to use the FlagsAttribute. In
my example below shouldn't both message boxes show? Instead no messagebox
displays. I know that .NET will auto-number enum's when omitted.
<snip>

If you don't specify values for your enum fields, they will be assigned
values in a straight sequence (1,2,3,4, etc...). If you want a "flagged"
enum you need to specify values that correspond to individual bit positions
(1,2,4,16, etc.):

<Flags()> Public Enum Permission
Read = 1
Write = 2
Delete = 4
Rename = 16
Copy = 32
Move = 64
End Enum

Hope that helps.

Regards,
Dan

p.s. *Should* the compiler be smart enough to auto-assign values correctly
if the "Flags" attribute is present? I think so.
 
Randy,
In addition to Daniel's suggestion of giving values to the Enum values.

<Flags()> Public Enum Permission
Read = 1
Write = 2
Delete = 4
Rename = 16
Copy = 32
Move = 64
End Enum

To combine the values you need to use Or.
Private p As Permission
p = Permission.Copy Or Permission.Read

Then you need to 'mask' the value and see if its not zero.

If (p and Permission.Copy) said:
MessageBox.Show("Copy")
End If

You can check for not zero or both values combined:
If (p and Permission.Copy Or Permission.Read) = (Permission.Copy Or
Permission.Read) Then
MessageBox.Show("Copy & Read")
End If

Sometimes when dealing with combined values, such as Read & Copy above, I
will define a constant that represents the two values combined

Const ReadAndCopy As Permission = Permission.Copy Or Permission.Read
If (p and ReadAndCopy ) = ReadAndCopy Then
MessageBox.Show("Copy & Read")
End If

Other times I will setup a function to check the masked values:

Private Function CheckMask(ByVal value As Permission, ByVal mask As
Permission)
Return (value And mask) = value
End Function

If CheckMask(p, Permission.Copy Or Permission.Read) Then
MessageBox.Show("Copy & Read")
End If

I will use the mask & value method when I want to check that out of Copy &
Read only Copy is set.

If (p and Permission.Copy Or Permission.Read) = Permission.Copy Then
MessageBox.Show("Of Copy & Read, only Copy set")
End If

When you think about it, one would expect And would be used to combine the
value (set theory). However enums are implemented as integers and boolean
theory is how they are worked with...

Hope this helps
Jay
 
This is something I find that .NET messed up.


if I specify the [Flags] attribute, why should I have to set the enum values
in powers of 2? Why cant the enum be smart enough to see that attribute and
set them accordingly. What is the benifit of the Flags attribute then? Its
lost. Pointless.
 
Mr.Tickle,
I won't disagree with you in that the compiler should figure out to use
Powers of two when you apply the Flags attribute and do not explicitly list
the values.
What is the benifit of the Flags attribute then?
The attribute controls the default behavior of the Enum.ToString method.

For example:

Private p As Permission
p = Permission.Copy Or Permission.Read

Debug.WriteLine(p, "Permission")

If Permission has the Flags attribute, then "Permission: Copy, Read" will be
printed, without the Flags attribute 33 will be printed. You can use one of
the Overloaded Enum.ToString methods to control this...

Hope this helps
Jay

Mr.Tickle said:
This is something I find that .NET messed up.


if I specify the [Flags] attribute, why should I have to set the enum values
in powers of 2? Why cant the enum be smart enough to see that attribute and
set them accordingly. What is the benifit of the Flags attribute then? Its
lost. Pointless.





Randy,
In addition to Daniel's suggestion of giving values to the Enum values.

<Flags()> Public Enum Permission
Read = 1
Write = 2
Delete = 4
Rename = 16
Copy = 32
Move = 64
End Enum

To combine the values you need to use Or.

p = Permission.Copy Or Permission.Read

Then you need to 'mask' the value and see if its not zero.



You can check for not zero or both values combined:
If (p and Permission.Copy Or Permission.Read) = (Permission.Copy Or
Permission.Read) Then

Sometimes when dealing with combined values, such as Read & Copy above, I
will define a constant that represents the two values combined

Const ReadAndCopy As Permission = Permission.Copy Or Permission.Read
If (p and ReadAndCopy ) = ReadAndCopy Then

Other times I will setup a function to check the masked values:

Private Function CheckMask(ByVal value As Permission, ByVal mask As
Permission)
Return (value And mask) = value
End Function

If CheckMask(p, Permission.Copy Or Permission.Read) Then

I will use the mask & value method when I want to check that out of Copy &
Read only Copy is set.

If (p and Permission.Copy Or Permission.Read) = Permission.Copy Then
MessageBox.Show("Of Copy & Read, only Copy set")
End If

When you think about it, one would expect And would be used to combine the
value (set theory). However enums are implemented as integers and boolean
theory is how they are worked with...

Hope this helps
Jay
 
Back
Top