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

时间:2015-01-13 15:19:41

标签: c# enums

我有一个Flag枚举

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

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

  • “Method1AndMethod2”(方法3)。
  • “Method1AndMethod4”(方法5)。
  • “Method2AndMethod4”(方法6)。
  • “Method1Method2AndMethod4”(方法7)。

    对于Flag Enum,最简单的方法是什么?

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

1 个答案:

答案 0 :(得分:1)

如果没有明确定义为枚举值的两个幂,它将无法工作。 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;

如果要检查某些Enumeration值是否包含Method1和/或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);
        }
    }
}