简体   繁体   English

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

[英]Bitmask'ed Int to Enum[] or Int[]? c#

I have an enum that looks like this: 我有一个看起来像这样的枚举:

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

Building the flag / bitmask is fine, but is it possible to do something like 构建标志/位掩码很好,但可以做类似的事情

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

Resulting in something like 导致像

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

Thanks. 谢谢。

Try the following 请尝试以下方法

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;
    }
  }
}

With this you can now write 有了这个你现在可以写

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

Note: This only works on enum values which derive from int (the default setting). 注意:这仅适用于从int派生的enum值(默认设置)。 It's also not entirely type safe as T can't be constrained to only enum values (nothing to do about that though) 它也不是完全类型安全的,因为T不能仅限于enum值(尽管如此)无关紧要

You can use the FlagsAttribute on the enum and get lots of the functionality for free (no need to work at the bit level). 您可以在枚举上使用FlagsAttribute并免费获得许多功能(无需在位级别工作)。

MSDN describes the attribute as: MSDN将该属性描述为:

Indicates that an enumeration can be treated as a bit field; 表示可以将枚举视为位字段; that is, a set of flags. 也就是说,一组标志。

The [FlagsAttribute] allows you to extract all of the valid values. [FlagsAttribute]允许您提取所有有效值。

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

Try this: 尝试这个:

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();
}

Call it like this: 像这样称呼它:

var bar = EnumSplit<foo>(i);

Preferably, you want to change it to return IEnumerable<TEnum> instead of TEnum[] . 最好,您希望将其更改为返回IEnumerable<TEnum>而不是TEnum[]

You could do this with a method which pulls the values from the Enum you pass: 您可以使用从您传递的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();;
}
    var flags = Enum.GetValues(typeof (/* YourEnumType */))
                  .Cast</* YourEnumType */>()
                  .Select(v => enumValue.HasFlag(v))
                  .ToArray();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM