Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert array of enum values to bit-flag combination

Tags:

c#

c#-2.0

How to create a bit-flag combination from an array of enum values in the simplest most optimal way in C# 2.0. I have actually figured out a solution but I am just not satisfied with the complexity here.

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);
}
like image 707
blins Avatar asked Sep 30 '11 22:09

blins


2 Answers

int result = 0;
foreach (MyEnum f in flags)
{
    result |= f; // You might need to cast — (int)f.
}
return result;

OTOH, you should use the FlagsAttribute for improved type safety:

[Flags]
enum MyEnum { ... }

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

Better still, by using FlagsAttribute you may be able to avoid using a MyEnum[] entirely, thus making this method redundant.

like image 177
Marcelo Cantos Avatar answered Nov 06 '22 13:11

Marcelo Cantos


Here's a shorter generic extension version:

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

And using:

[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);
}
like image 34
LbISS Avatar answered Nov 06 '22 14:11

LbISS