如何在组合中列出基于枚举
本文关键字:于枚举 枚举 组合 | 更新日期: 2023-09-27 18:28:32
是否可以组合列出一个标志。
使用ProfileTypeFlag.SupplierMaster只获取"Supplier|Master|External"的列表
我正在尝试使用此代码。但他们会返回所有枚举;
public List<string> SetRoles(ProfileTypeFlag role)
{
List<string> result = new List<string>();
foreach (ProfileTypeFlag r in Enum.GetValues(typeof(ProfileTypeFlag)))
{
if ((role & r) != 0) result.Add(r.ToString());
}
return result;
}
[Flags]
public enum ProfileTypeFlag : uint
{
None = 0,
Customer = 1,
Supplier = 2,
Internal = 4,
Delegate = 8,
Master = 16,
External = 32,
CustomerMaster = Customer | Master | External,
SupplierMaster = Supplier | Master | External
}
这里有一个适合您的解决方案:
public static string GetFlagsStringFromUInt32Enum<TEnum>(TEnum value)
where TEnum : struct
{
var sb = new StringBuilder();
for(var i = 0; i < 32; ++i)
{
var bit = (uint)1 << i;
if (((uint)(object)value & bit) != 0)
sb.Append((TEnum)(object)bit).Append(" | ");
}
if (sb.Length > 0)
sb.Length -= 3;
return sb.ToString();
}
演示
这将适用于基于uint
的枚举,就像您的一样,我不想实现通用解决方案。
只需稍微调整if
语句:
if ((role & r) == r && r != ProfileTypeFlag.None && role != r)
或者您可以使用HasFlag
(相当于role & r == r
):
if (role.HasFlag(r) && r != ProfileTypeFlag.None && role != r)
基本上,如果角色包含标志,则不是None
标志,也不是角色本身,然后将其添加到列表中。
考虑到这一点,您可以将整个功能更改为:
public List<string> SetRoles(ProfileTypeFlag role)
{
return
Enum.GetValues(typeof(ProfileTypeFlag))
.Cast<ProfileTypeFlag>()
.Where(r => r != ProfileTypeFlag.None)
.Where(r => r != role)
.Where(r => role.HasFlag(r))
.Select(r => r.ToString())
.ToList();
}
正如@Lucas所指出的,如果您的枚举值包含复合标志,那么上述解决方案就无法正常工作。
对此的一个解决方案是在遇到标志值时删除它们:
public List<string> SetRoles(ProfileTypeFlag role)
{
var result = new List<string>();
foreach (ProfileTypeFlag r in Enum.GetValues(typeof(ProfileTypeFlag)))
{
if (role.HasFlag(r) && r != ProfileTypeFlag.None)
{
result.Add(r.ToString());
role &= ~r;
}
}
return result;
}
为了提供一种稍微不同的方法,您可以使用此函数来获取"set"enums:
static IEnumerable<Enum> GetFlags(Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value))
yield return value;
}
归功于@Greg(遍历Flags Enum中的值?)
然后这样称呼它:
List<string> names = GetFlags(enumValue).Select(e => e.ToString()).ToList();