Frage

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.

War es hilfreich?

Lösung

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.

Andere Tipps

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

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

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.

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.

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top