2014-10-29 20 views
0

可能列出基于组合的标志。如何列出基于组合的枚举

使用ProfileTypeFlag.SupplierMaster得到公正的“供应商|大师|外部”列表

我想利用这个代码。但他们返回所有枚举;

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 
} 
+0

好的......你想要发生什么? – BradleyDotNET 2014-10-29 23:59:24

+0

返回一个列表 =“供应商”,“主”,“外部”或列表与“供应商”,“主”,“外部” – AFetter 2014-10-30 00:03:05

回答

1

这里有一个解决方案为您:

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

Demo

这将基于uint像你枚举工作,我ddn't刻意去实现一个通用的解决方案。

1

只要稍微调整你的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; 
} 
+0

+1实际修复他的代码。 – BradleyDotNET 2014-10-30 00:10:54

+0

我想它会突破'ProfileTypeFlag.SupplierMaster | ProfileTypeFlag.Internal' – 2014-10-30 00:15:34

+0

@LucasTrzesniewski:你说得对,你的解决方案可能会更好 – 2014-10-30 00:21:14

0

为了提供一个稍微不同的方法,你可以使用这个函数来获取“设置”枚举:

static IEnumerable<Enum> GetFlags(Enum input) 
{ 
    foreach (Enum value in Enum.GetValues(input.GetType())) 
     if (input.HasFlag(value)) 
      yield return value; 
} 

感谢@格雷格(Iterate over values in Flags Enum?

然后调用它是这样:

List<string> names = GetFlags(enumValue).Select(e => e.ToString()).ToList();