将枚举值数组转换为位标志组合

时间:2011-09-30 22:41:24

标签: c# c#-2.0

如果这是一个骗局或者只是一个无聊的问题,我会向前道歉。此外,我将通过我实际找到答案来证明这一点。我对复杂性感到不满意(因为这很无聊))。

问题:

如何在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 个答案:

答案 0 :(得分:10)

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[],从而使此方法变得多余。

答案 1 :(得分:2)

这是一个较短的通用扩展版本:

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