计算标志枚举的两个值的非幂

本文关键字:两个 标志 枚举 计算 | 更新日期: 2023-09-27 18:37:18

我有一个标志枚举

[Flag] 
public enum Enumeration{
      None
      Method1
      Method2
      Method4
}

我想计算"缺失"值,例如,在上面的枚举中,我需要找到

  • "方法1和方法2"(方法3)。

  • "方法1和方法4"(方法5)。

  • "方法2和方法4"(方法6)。

  • "方法1方法2和方法4"(方法7)。

    对于标志枚举,最简单的方法是什么?

我已经确定了程序集中的哪些枚举是 flags.so 我只需要一种方法来遍历并计算缺失值。

计算标志枚举的两个值的非幂

如果没有明确定义为枚举值的两个幂,它将无法工作。 Flags属性本身只影响枚举的字符串表示形式(例如,调用yourEnumerationValue.ToString()时)。所以首先:

[Flags] 
public enum Enumeration{
      None = 1,
      Method1 = 2,
      Method2 = 4,
      Method4 = 8
      // etc.
}

顺便说一句,它是Flags,而不是Flag.

以这种方式设置时,将使用按位运算。使用按位 OR 对枚举项进行"求和"

Enumeration method3 = Enumeration.Method1 | Enumeration.Method2;

如果要检查某些枚举值是否包含方法1和/或方法2,请按如下方式操作:

Enumeration someValue = // whatever value you want here
bool containsMethod1 = someValue & Enumeration.Method1 == Enumeration.Method1;
bool containsMethod2 = someValue & Enumeration.Method2 == Enumeration.Method2;
bool containsBoth = someValue & method3 == method3;

另一方面,你不能真正拥有"Method1和Method2"。它们是不同的东西,因此 Method1 不等于 Method2,除非您为它们分配相同的值,但它们只是彼此的别名。

编辑:从.NET 4.0开始,有一种更简单的方法来检查枚举值是否包含标志:

bool containsMethod1 = someValue.HasFlag(Enumeration.Method1);
bool containsBoth = someValue.HasFlag(method3);
// or .HasFlag(Enumeration.Method1 | Enumeration.Method2)

这是一个简单的解决方案,将提供的 MyEnum 枚举中的所有缺失值写入控制台:

[Flags]
enum MyEnum
{
    Manual = 1,
    Site = 2,
    Api = 4,
    Custom = 8
}
static void Main(string[] args)
{
    // SortedSet is not necessary but it has convenient Min and Max properties.
    SortedSet<MyEnum> enumValues = new SortedSet<MyEnum>();
    foreach (MyEnum e in Enum.GetValues(typeof(MyEnum)))
        enumValues.Add(e);
    // enumValues.Max * 2 to check all combinations including the last flag.
    for (int i = (int)enumValues.Min + 1; i < (int)enumValues.Max * 2; i++)
    {
        MyEnum currentlyChecked = (MyEnum)i;
        // if there's no equivalent of i defined in MyEnum
        if (!enumValues.Contains(currentlyChecked))
        {
            string representation = "";
            // Iterate over all MyEnum flags which underlying value is lower than i
            // and add those flags which are contained in (MyEnum)i to the string representation
            // of the value missing from the MyEnum enumeration.
            foreach (MyEnum lowerValue in enumValues.Where(e => (int)e < i))
            {
                if (currentlyChecked.HasFlag(lowerValue))
                    representation += lowerValue.ToString();
            }
            if (String.IsNullOrEmpty(representation))
                representation = "[MISSING FLAG]";
            Console.WriteLine("Missing value: {0} - {1}", i, representation);
        }
    }
}