What does the [Flags] Enum Attribute mean in C#?

前端 未结 13 2223
慢半拍i
慢半拍i 2020-11-21 04:21

From time to time I see an enum like the following:

[Flags]
public enum Options 
{
    None    = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Op         


        
相关标签:
13条回答
  • 2020-11-21 04:58
    • Flags are used when an enumerable value represents a collection of enum members.

    • here we use bitwise operators, | and &

    • Example

                   [Flags]
                   public enum Sides { Left=0, Right=1, Top=2, Bottom=3 }
      
                   Sides leftRight = Sides.Left | Sides.Right;
                   Console.WriteLine (leftRight);//Left, Right
      
                   string stringValue = leftRight.ToString();
                   Console.WriteLine (stringValue);//Left, Right
      
                   Sides s = Sides.Left;
                   s |= Sides.Right;
                   Console.WriteLine (s);//Left, Right
      
                   s ^= Sides.Right; // Toggles Sides.Right
                   Console.WriteLine (s); //Left
      
    0 讨论(0)
  • 2020-11-21 05:00

    You can also do this

    [Flags]
    public enum MyEnum
    {
        None   = 0,
        First  = 1 << 0,
        Second = 1 << 1,
        Third  = 1 << 2,
        Fourth = 1 << 3
    }
    

    I find the bit-shifting easier than typing 4,8,16,32 and so on. It has no impact on your code because it's all done at compile time

    0 讨论(0)
  • 2020-11-21 05:00

    @Nidonocu

    To add another flag to an existing set of values, use the OR assignment operator.

    Mode = Mode.Read;
    //Add Mode.Write
    Mode |= Mode.Write;
    Assert.True(((Mode & Mode.Write) == Mode.Write)
      && ((Mode & Mode.Read) == Mode.Read)));
    
    0 讨论(0)
  • 2020-11-21 05:07

    Flags allow you to use bitmasking inside your enumeration. This allows you to combine enumeration values, while retaining which ones are specified.

    [Flags]
    public enum DashboardItemPresentationProperties : long
    {
        None = 0,
        HideCollapse = 1,
        HideDelete = 2,
        HideEdit = 4,
        HideOpenInNewWindow = 8,
        HideResetSource = 16,
        HideMenu = 32
    }
    
    0 讨论(0)
  • 2020-11-21 05:12

    I asked recently about something similar.

    If you use flags you can add an extension method to enums to make checking the contained flags easier (see post for detail)

    This allows you to do:

    [Flags]
    public enum PossibleOptions : byte
    {
        None = 0,
        OptionOne = 1,
        OptionTwo = 2,
        OptionThree = 4,
        OptionFour = 8,
    
        //combinations can be in the enum too
        OptionOneAndTwo = OptionOne | OptionTwo,
        OptionOneTwoAndThree = OptionOne | OptionTwo | OptionThree,
        ...
    }
    

    Then you can do:

    PossibleOptions opt = PossibleOptions.OptionOneTwoAndThree 
    
    if( opt.IsSet( PossibleOptions.OptionOne ) ) {
        //optionOne is one of those set
    }
    

    I find this easier to read than the most ways of checking the included flags.

    0 讨论(0)
  • 2020-11-21 05:13

    Combining answers https://stackoverflow.com/a/8462/1037948 (declaration via bit-shifting) and https://stackoverflow.com/a/9117/1037948 (using combinations in declaration) you can bit-shift previous values rather than using numbers. Not necessarily recommending it, but just pointing out you can.

    Rather than:

    [Flags]
    public enum Options : byte
    {
        None    = 0,
        One     = 1 << 0,   // 1
        Two     = 1 << 1,   // 2
        Three   = 1 << 2,   // 4
        Four    = 1 << 3,   // 8
    
        // combinations
        OneAndTwo = One | Two,
        OneTwoAndThree = One | Two | Three,
    }
    

    You can declare

    [Flags]
    public enum Options : byte
    {
        None    = 0,
        One     = 1 << 0,       // 1
        // now that value 1 is available, start shifting from there
        Two     = One << 1,     // 2
        Three   = Two << 1,     // 4
        Four    = Three << 1,   // 8
    
        // same combinations
        OneAndTwo = One | Two,
        OneTwoAndThree = One | Two | Three,
    }
    

    Confirming with LinqPad:

    foreach(var e in Enum.GetValues(typeof(Options))) {
        string.Format("{0} = {1}", e.ToString(), (byte)e).Dump();
    }
    

    Results in:

    None = 0
    One = 1
    Two = 2
    OneAndTwo = 3
    Three = 4
    OneTwoAndThree = 7
    Four = 8
    
    0 讨论(0)
提交回复
热议问题