【问题标题】:How get not containing flags如何获取不包含标志
【发布时间】:2018-09-20 07:48:11
【问题描述】:

我有枚举标志。如何获取不包含特定标志的所有标志组合?

[Flags]
public enum TestEnum
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}

public static IEnumerable<Enum> AllNotContaining(this Enum value)
{....}

例如,TestEnum.A.AllNotContaining() 应该返回 {2, 4, 6, 8, 10, 12, 14}

【问题讨论】:

  • 所以如果value = TestEnum.A | TestEnum.C 你希望你的函数返回{ TestEnum.B, TestEnum.D }?
  • 示例 TestEnum.A.AllNotContaining() 返回 {2, 4 ,8, 6, 10, 12, 14}
  • 将您的示例添加到问题中。此处不计评论。
  • @panmigal 请注意,标记的枚举应仅具有 2^x = {1,2,4,8,16,32,...} 的值。否则会导致错误。
  • @Chrᴉz:我想您会发现,当枚举值不是 2 的幂时,Flags 属性不会导致任何错误。见:stackoverflow.com/questions/8447/…

标签: c# enums flags enum-flags


【解决方案1】:

第一步,使用二进制NOT:

var notUsedBits = ~ value;

但这会设置所有未使用的 32 位。

所以你可能会想要一个面具:

[Flags]
public enum TestEnum
{
    A = 1,
    B = 2,
    C = 4,
    D = 8,    
    All = A|B|C|D,  // or compute this inside the method    
}

然后方法就变成了

// untested
public static TestEnum AllNotContaining(this TestEnum value)
{
    return ~ value & TestEnum.All;
}

这不会返回 IEnumerable,但对于 Flags 枚举来说这很奇怪(而且效率低下)。

【讨论】:

    【解决方案2】:

    我没有尝试完善下面的代码,但你应该大致了解一下:

      public static IEnumerable<int> AllNotContaining<T>(this T value)
        // where T : Enum  (as of C# 7.3).
      {
        // Determine upper bound of values to check.
        // E.g. for your test enum, the maximum value is 8 so we need to check up to 15.
        var values = Enum.GetValues(typeof(T)).Cast<int>();
        int max = values.Max() * 2 - 1;
    
        // Test all values to see if the given flag is present. If not, return it.
        for(int i = 0; i <= max; ++i)
        {
          // Possibly also: if( ((Enum)i).HasFlags(value))
          if((max & Convert.ToInt32(value)) == 0)
          {
            yield return i;
          }
        }
      }
    

    【讨论】:

      【解决方案3】:

      试试这样:

      public static IEnumerable<TestEnum> AllNotContaining(this TestEnum value)
      {
          return Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>().Where(x => x != value).AsEnumerable();
      }
      

      【讨论】:

      • != 不足以用于标志枚举 - 考虑 (A|C).AllNotContaining()
      猜你喜欢
      • 2015-08-19
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多