Using Bitwise operators on flags

后端 未结 9 1874
生来不讨喜
生来不讨喜 2020-12-23 12:11

I have four flags

Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7

Say I receive the two flags Past and Future (setFlags(PAST

相关标签:
9条回答
  • 2020-12-23 12:29
    (value & Current) == Current
    
    0 讨论(0)
  • 2020-12-23 12:34

    If you use .NET 4 or later I prefer to do this, cleaner imao:

    [Flags]
    public enum Time
    {
        None = 0
        Current = 1,
        Past = 2,
        Future = 4
    }
    
    myProp = Time.Past | Time.Future;
    
    if (myProp.HasFlag(Time.Past))
    {
        // Past is set...
    }
    
    0 讨论(0)
  • 2020-12-23 12:36

    you could use AND on it and check if the result is the same as you and with?

    0 讨论(0)
  • 2020-12-23 12:39

    First of all - use enums with FlagAttribute. That's what it's for.

    [Flags]
    public enum Time
    {
        None = 0
        Current = 1,
        Past = 2,
        Future = 4
        All = 7
    }
    

    Testing then is done like this:

    if ( (x & Time.Past) != 0 )
    

    Or this:

    if ( (x & Time.Past) == Time.Past )
    

    The latter will work better if "Past" was a combination of flags and you wanted to test them all.

    Setting is like this:

    x |= Time.Past;
    

    Unsetting is like this:

    x &= ~Time.Past;
    
    0 讨论(0)
  • 2020-12-23 12:41

    You may also want to add an extension method like this

      enum states {
         Current = 0x1,
         Past = 0x2,
         Future = 0x4,
         All = 0x7
      };
    
      static bool Is(this states current, states value) {
         return (current & value) == value;
      }
    

    then you can do:

     if(state.Is(states.Past)) {
        // Past
     }
    
    0 讨论(0)
  • 2020-12-23 12:46

    An addendum to Marc Gravell and Vilx-'s answer:

    Your flagged enum shouldn't specify the amount for "All", it should just include your existing values. This goes for any calculated values.

    [Flags]
    public enum Time
    {
        None = 0,
        Current = 1,
        Past = 2,
        Future = 4,
        All = Current | Past | Future
    }
    

    Note that Vilx- removed the use of Hexadecimal for values. This is important because once you're past 0x8, your values will have to comply with Hex. You should just stay in decimal.

    EDIT: I also want to add that you can use bit shifting rather than hex/decimal.

    This looks like:

    [Flags]
    public enum Time
    {
        None = 0,
        Current = 1,
        Past = 1 << 1, // 2, 10 binary
        Future = 1 << 2, // 4, 100 binary
        All = Current | Past | Future
    }
    
    0 讨论(0)
提交回复
热议问题