我花了幾個小時試圖找出將Enum掩碼轉換爲Enum值數組的一般方式,相反,Enum值數組枚舉掩碼。將標誌轉換爲IEnumerable的擴展方法<Enum>反過來(C#)
寫一個擴展方法這樣做是有點痛苦,所以我只是想分享我的解決方案,以防它可以幫助某人。我相信它可以改進,但在這裏!
我花了幾個小時試圖找出將Enum掩碼轉換爲Enum值數組的一般方式,相反,Enum值數組枚舉掩碼。將標誌轉換爲IEnumerable的擴展方法<Enum>反過來(C#)
寫一個擴展方法這樣做是有點痛苦,所以我只是想分享我的解決方案,以防它可以幫助某人。我相信它可以改進,但在這裏!
下面的擴展方法從枚舉值列表返回一個掩碼。
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());
}
下面的擴展方法返回一個掩碼的枚舉值列表。
public static IEnumerable<T> ToValues<T>(this T flags) where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
throw new ArgumentException("T must be an enumerated type.");
int inputInt = (int)(object)(T)flags;
foreach (T value in Enum.GetValues(typeof(T)))
{
int valueInt = (int)(object)(T)value;
if (0 != (valueInt & inputInt))
{
yield return value;
}
}
}
需要注意的是:在C#(where T : ...
)
[Flags]
屬性(不能找出答案)用法:
[Flags]
public enum TestEnum : int
{
None = 0,
Plop = 1,
Pouet = 2,
Foo = 4,
Bar = 8
}
要掩模:
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);
非常好的擴展方法,謝謝。 – Lopsided
我需要一個簡單的解決方案,用於將相反的方向(而不是必須包括擴展名),所以這裏的一個LINQ溶液到將你枚舉的IEnumerable變成標記的枚舉:
MyEnum e = MyEnumList.Aggregate((MyEnum)0, (a,b) => a |= b);
爲什麼你想要將枚舉掩碼轉換爲枚舉數組?你會怎麼做,你不能直接使用面膜? – Chris
還有天哪。它真的很煩人的擴展方法的枚舉是不是?你可以做'enums.Aggregate((x,y)=> x | y);'作爲一個非常快速的方法來枚舉值來屏蔽,但由於所有其他代碼你需要包裝它來處理轉換等 – Chris
我的數據庫包含掩碼,但我的REST API公開了值列表。所以我需要一種方便來回的方法。我沒有想過總計,你有一個好點! – Pedro