Преобразовать массив значений перечисления в комбинацию битовых флагов - PullRequest
7 голосов
/ 01 октября 2011

Я заранее извиняюсь, если это глупость или просто скучный вопрос, и более того, я квалифицирую это с тем фактом, что я действительно нашел ответ.Я просто не удовлетворен сложностью (как бы скучно это не было:))

ВОПРОС:

Как создать комбинацию битовых флагов из массива значений перечисления в простейшем наиболее оптимальномпуть в C # 2.0

ПРИМЕРНЫЙ КОД (Не уверен, что это лучшее, что мы можем сделать здесь):

enum MyEnum
{
    Apple = 0,
    Apricot = 1,
    Breadfruit = 2,
    Banana = 4
}

private int ConvertToBitFlags(MyEnum[] flags)
{
    string strFlags = string.Empty;
    foreach (MyEnum f in flags)
    {
        strFlags += strFlags == string.Empty ?
            Enum.GetName(typeof(MyEnum), f) :
            "," + Enum.GetName(typeof(MyEnum), f);
    }
    return (int)Enum.Parse(typeof(MyEnum), strFlags);
}

Ответы [ 2 ]

10 голосов
/ 01 октября 2011
int result = 0;
foreach (MyEnum f in flags)
{
    result |= f; // You might need to cast — (int)f.
}
return result;

OTOH, вы должны использовать FlagsAttribute для улучшения безопасности типов:

[Flags]
enum MyEnum { ... }

private MyEnum ConvertToBitFlags(MyEnum[] flags)
{
    MyEnum result = 0;
    foreach (MyEnum f in flags)
    {
        result |= f;
    }
    return result;
}

Более того, используя FlagsAttribute, вы можете избежать использования MyEnum[] полностью, что делает этот метод избыточным.

3 голосов
/ 18 мая 2017

Вот более короткая общая расширенная версия:

public static T ConvertToFlag<T>(this IEnumerable<T> flags) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
        throw new NotSupportedException($"{typeof(T).ToString()} must be an enumerated type");

    return (T)(object)flags.Cast<int>().Aggregate(0, (c, n) => c |= n);
}

И с использованием:

[Flags]
public enum TestEnum
{
    None = 0,
    Test1 = 1,
    Test2 = 2,
    Test4 = 4
}

[Test]
public void ConvertToFlagTest()
{
    var testEnumArray = new List<TestEnum> { TestEnum.Test2, TestEnum.Test4 };

    var res = testEnumArray.ConvertToFlag();

    Assert.AreEqual(TestEnum.Test2 | TestEnum.Test4, res);
}
...