Bitmask'ed Int到Enum []或Int []? C#

时间:2011-03-29 16:10:43

标签: c# bitmask

我有一个看起来像这样的枚举:

enum foo{
a=0,
b=1,
c=2,
d=4
}

构建标志/位掩码很好,但可以执行类似

的操作
int i = 3;
var bar =  Enum.Split(foo,i);

导致类似

的内容
bar = foo[]{a, b,c};

感谢。

6 个答案:

答案 0 :(得分:7)

尝试以下

public static IEnumerable<T> Split<T>(int value) {
  foreach (object cur in Enum.GetValues(typeof(T))) {
    var number = (int)(object)(T)cur;
    if (0 != (number & value)) {
      yield return (T)cur;
    }
  }
}

有了这个你现在可以写

int i = 3;
IEnumerable<foo> e = Split<foo>(i);

注意:这仅适用于源自enum的{​​{1}}值(默认设置)。它也不是完全类型安全的,因为int不能仅限于T值(尽管如此)无关紧要。

答案 1 :(得分:3)

您可以在枚举上使用FlagsAttribute并免费获得许多功能(无需在位级别工作)。

MSDN将该属性描述为:

  

表示可以将枚举视为位字段;也就是说,一组标志。

答案 2 :(得分:2)

[FlagsAttribute]允许您提取所有有效值。

http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx

答案 3 :(得分:2)

试试这个:

TEnum[] EnumSplit<TEnum>(int mask)
{
    List<TEnum> values = new List<TEnum>();
    foreach(int enumValue in Enum.GetValues(typeof(TEnum)))
    {
        if(mask & enumValue == enumValue)
            values.Add((TEnum)enumValue);
    }
    return values.ToArray();
}

这样称呼:

var bar = EnumSplit<foo>(i);

最好,您要将其更改为返回IEnumerable<TEnum>而不是TEnum[]

答案 4 :(得分:1)

您可以使用一种方法来执行此操作,该方法从您传递的Enum中提取值:

public static T[] EnumSplit<T>(int value) where T : struct
{
    // Simplified as Enum.GetValues will complain if T is not an enum
    // However, you should add a check to make sure T implements FlagAttribute
    return (from vv in Enum.GetValues(typeof(T))
            where ((int)vv & value) != 0
            select (T)vv).ToArray();;
}

答案 5 :(得分:0)

    var flags = Enum.GetValues(typeof (/* YourEnumType */))
                  .Cast</* YourEnumType */>()
                  .Select(v => enumValue.HasFlag(v))
                  .ToArray();
相关问题