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

Calculating Non-Power of Two values for flag enumeration

我有一个标志枚举

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

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

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

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

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

对了,是Flags,不是Flag

当你以这种方式设置它时,你使用的是位运算。使用按位或运算 "sum" 枚举项

Enumeration method3 = Enumeration.Method1 | Enumeration.Method2;

如果你想检查一些枚举值是否包含 Method1 and/or Method2,你可以这样做:

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;

另一方面,你不可能真正拥有 "Method1AndMethod2"。它们是独立的事物,因此 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);
        }
    }
}