What Does the [Flags] Attribute Really Do?
Asked Answered
K

6

31

What does applying [Flags] really do?

I know it modifies the behavior of Enum.ToString, but does it do anything else? (e.g. Different compiler or runtime behavior, etc.)


Edit: Yeah, I'm aware that it documents the fact that the enum is intended to be used as bitwise flags, and that it's more logical to apply it to bit flags. I was asking more about concrete behavior changes though, not general programming practices.

Kenweigh answered 5/5, 2011 at 19:18 Comment(4)
Take a look at msdn.microsoft.com/en-us/library/ms229062.aspxTie
@SQLMenace: That just says when I should apply it and how I should write my code, not if it changes the behavior of anything. :\Kenweigh
+1 I've asked myself this many timesGarry
I'd like to see @Eric Lippert comment on this.Precatory
M
31

From an MSDN article:

It is interesting to note that when Flags is specified, Parse and Format methods feature advanced capabilities.

Likewise, the Parse method can successfully parse a comma-separated string like the one just shown into the proper numeric value.

Marchall answered 5/5, 2011 at 19:34 Comment(1)
+1 seems to be the best answer answer so far. I had no idea it changes the behavior of Parse...Kenweigh
P
17

See David M. Kean's post here. This appears to be a language interop issue:

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

Precatory answered 5/5, 2011 at 19:54 Comment(3)
+1 great (and unexpected) answer. :) (Although I have to admit, to me ".NET" is pretty much just different forms of the same language. Still a great answer, though.)Kenweigh
your answer would be even better if you copied the content of that post into your answer.Letreece
Hrmm... I just checked, and VB does not auto-assign [flag] enums as powers of 2, as this post implies. It increments them in the usual way -- by 1.Manvel
M
10

Here's a list of concrete behavioral differences:

  • Setting an enum with [flags] to None clears all the flags.
  • The HasFlags method only works when this attribute is present.
  • As Devio said, it changes the capabilities of the Parse and Format methods. He linked to this article. Apparently it also impacts that is shown in Debuggers.
  • I thought [flags] probably had an impact on code generation in webservices, but it appears that this is not the case.
  • To be clear, bitwise operations are allowed on any enumeration, with or without [flags]. But using it is the best practice.

More details: http://msdn.microsoft.com/en-us/library/ms229062.aspx

Manvel answered 5/5, 2011 at 19:22 Comment(0)
O
5

If you ask what it does under the hood, as far as I know, it changes the ToString() method, nothing other.

Under .Net 4 you have the HasFlags-method to check for specific flags. If I interpret msdn right, you have to use the flags-attribute for using this method. But I have not tried it.

Overcritical answered 5/5, 2011 at 19:23 Comment(0)
I
1

In practice, one of the uses I use is indicating multiple statuses. This is a simplification of some code that evaluates test results. The test can be Ok, or it could have several reasons for not being Ok. The advantage this gives, is I have one method that evaluates the tests "Ok-ness", and that method is able to indicate all the possible failure conditions with one return. May not be the best design, but it works in this case.

[Flags]
public enum ResultStatusEnum
{
    Ok = 0x1,
    SampleInvalid = 0x2,
    DirectionInvalid = 0x4,
    TestIsNotValid = 0x8
}

You set it like this:

ResultStatusEnum res = ResultStatusEnum.SampleInvalid | ResultStatusEnum.DirectionInvalid;

The disadvantage is that checking the values of the enum becomes cumbersome. This won't (necessarily) work:

res == ResultStatusEnum.Ok

You have to do this to check:

ResultStatusEnum.SampleInvalid == (res & ResultStatusEnum.SampleInvalid)

In this case, its illogical to have ResultStatusEnum.Ok & ResultStatusEnum.SampleInvalid, but I just make sure this isn't the case where I use the enum.

Inevitable answered 5/5, 2011 at 19:32 Comment(2)
Yes, but if it's not decorated as such, other languages may/may not handle the enum properly. If it's all in C#, I guess it doesn't really matter. When I see it, though, I expect this kind of use. Without it, I DON'T expect to see a bit wise use. So it's helpful for readability.Inevitable
Depends on what you mean by "handle" I guess. They could certainly still do bitwise operations on them in the same manner, but whether or not they would allow them in the first place seems to be an issue, according to what Charles posted.Kenweigh
G
0

Flags gives an option to use enum for multiple value.

Consider a situation where you want to use Checkboxes for different situation but you do not want to create different columns in the database. If you have 20 check boxes you will have to create 20 columns in the database with bool. But with flags you can create one column and use that value to store in the column. Run this example in the console to understand it better.

class Program
{
    static void Main(string[] args)
    {
        //Set the features that you require for car. Consider it as checked in the UI.
        CarFeatures carFeatures = CarFeatures.AC | CarFeatures.Autopilot| CarFeatures.Sunroof;

        //Do the backend logic
        if (carFeatures.HasFlag(CarFeatures.Autopilot))
        {
            //Show Autopilot cars
        }
        //See the what carfeatures are required
        Console.WriteLine(carFeatures);
        //See the integer value of the carfeatures
        Console.WriteLine((int)carFeatures);
        Console.ReadLine();
    }
}

[Flags]
public enum CarFeatures
{
    AC=1,
    HeatedSeats= 2,
    Sunroof= 4,
    Autopilot= 8,
}

The different combination always gives you a unique number which c# tracks back to find what all are marked.

Graphophone answered 21/8, 2018 at 19:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.