Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将标志转换为IEnumerable的扩展方法<;Enum>;反之(C#)_C#_Enums_Extension Methods_Ienumerable - Fatal编程技术网

将标志转换为IEnumerable的扩展方法<;Enum>;反之(C#)

将标志转换为IEnumerable的扩展方法<;Enum>;反之(C#),c#,enums,extension-methods,ienumerable,C#,Enums,Extension Methods,Ienumerable,我花了几个小时试图找出一种通用方法,将枚举掩码转换为枚举值数组,反之,将枚举值数组转换为枚举掩码 编写一个扩展方法来实现这一点有点痛苦,所以我只想与大家分享我的解决方案,以防它能帮助别人。我相信它可以改进,但是,在这里 下面的扩展方法从枚举值列表返回掩码 public static T ToMask<T>(this IEnumerable<T> values) where T : struct, IConvertible { if (!typeof(T).IsEn

我花了几个小时试图找出一种通用方法,将枚举掩码转换为枚举值数组,反之,将枚举值数组转换为枚举掩码


编写一个扩展方法来实现这一点有点痛苦,所以我只想与大家分享我的解决方案,以防它能帮助别人。我相信它可以改进,但是,在这里

下面的扩展方法从枚举值列表返回掩码

public static T ToMask<T>(this IEnumerable<T> values) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enumerated type.");

     int builtValue = 0;
     foreach (T value in Enum.GetValues(typeof(T)))
     {
        if (values.Contains(value))
        {
            builtValue |= Convert.ToInt32(value);
        }
    }
    return (T)Enum.Parse(typeof(T), builtValue.ToString());
}
掩盖:

TestEnum[] enums = new[] { TestEnum.None, TestEnum.Plop, TestEnum.Foo };
TestEnum flags = enums.ToMask();

TestEnum expectedFlags = TestEnum.None | TestEnum.Plop | TestEnum.Foo;
Assert.AreEqual(expectedFlags, flags);
对价值观:

TestEnum flags = TestEnum.None | TestEnum.Plop | TestEnum.Foo;
TestEnum[] array = flags.ToValues().ToArray();

TestEnum[] expectedArray = new[] { TestEnum.Plop, TestEnum.Foo };
CollectionAssert.AreEqual(expectedArray, array);

我需要一个简单的解决方案来转换相反的方向(而不必包括扩展),因此这里有一个Linq解决方案,可以将枚举的IEnumerable转换为带标记的枚举:

MyEnum e = MyEnumList.Aggregate((MyEnum)0, (a,b) => a |= b);

为什么要将枚举掩码转换为枚举数组?如果你不能直接用面具,你会用它做什么?天哪。为枚举编写扩展方法真的很烦人,不是吗?您可以执行
enums.Aggregate((x,y)=>x | y)
作为一种非常快速的方法,可以将枚举值屏蔽,但将其放入扩展方法中是一种痛苦,因为您需要包装它来处理转换等所有其他代码。我的数据库包含屏蔽,但我的REST API公开了值列表。所以我需要一个方便的来回方式。我没有考虑总数,你说得很对!
TestEnum flags = TestEnum.None | TestEnum.Plop | TestEnum.Foo;
TestEnum[] array = flags.ToValues().ToArray();

TestEnum[] expectedArray = new[] { TestEnum.Plop, TestEnum.Foo };
CollectionAssert.AreEqual(expectedArray, array);
MyEnum e = MyEnumList.Aggregate((MyEnum)0, (a,b) => a |= b);