Битовая маска Int в Enum [] или Int []? C # - PullRequest
3 голосов
/ 29 марта 2011

У меня есть перечисление, которое выглядит так:

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 ]

7 голосов
/ 29 марта 2011

Попробуйте следующее

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 значений, которые получены из int (настройка по умолчанию). Это также не совсем безопасно для типов, так как T не может быть ограничен только значениями enum (с этим ничего не поделать)

3 голосов
/ 29 марта 2011

Вы можете использовать FlagsAttribute для перечисления и получить множество функций бесплатно (не нужно работать на битовом уровне).

MSDN описывает атрибут следующим образом:

Указывает, что перечисление может рассматриваться как битовое поле;то есть набор флагов.

2 голосов
/ 29 марта 2011

Попробуйте это:

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[].

2 голосов
/ 29 марта 2011

[FlagsAttribute] позволяет извлечь все допустимые значения.

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

1 голос
/ 29 марта 2011

Вы можете сделать это с помощью метода, который извлекает значения из 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();;
}
0 голосов
/ 29 марта 2011
    var flags = Enum.GetValues(typeof (/* YourEnumType */))
                  .Cast</* YourEnumType */>()
                  .Select(v => enumValue.HasFlag(v))
                  .ToArray();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...