将标记的枚举解析为列表的最有效方法

时间:2010-09-08 14:03:30

标签: c# enums

我有一个标记的枚举,需要检索其上设置的所有值的名称。

我目前正在利用枚举的ToString()方法,它返回以逗号分隔的元素。

    public void SetRoles(Enums.Roles role)
    {
        IList<Entities.Role> roleList = role.ToString("G").Split(',')
            .Select(r => new Entities.Role(r.Trim()))
            .ToList();
    ...
    }

我确信必须有比这更好的方法。

6 个答案:

答案 0 :(得分:27)

好问题!

我想不出更好的事情:

public void SetRoles(Enums.Roles role)
{
  List<string> result = new List<string>();
  foreach(Roles r in Enum.GetValues(typeof(Roles))
  {
    if ((role & r) != 0) result.Add(r.ToString());
  }
}

答案 1 :(得分:25)

如果你真的只想要字符串,就不会比以下简单得多:

string[] flags = role.ToString().Split(',');

这比使用LINQ简单,并且仍然只是一行代码。 或者,如果您需要列表而不是问题中的示例中的数组,则可以将数组转换为列表:

List<string> flags = new List<string>(role.ToString().Split(','));

在我的情况下,我需要一个通用的解决方案,并想出了这个:

value.ToString().Split(',').Select(flag => (T)Enum.Parse(typeof(T), flag)).ToList();

答案 2 :(得分:7)

Enum.Parse将处理ToString输出的连接值就好了。使用立即窗口证明:

? System.Enum.Parse(typeof(System.AttributeTargets), "Class, Enum")
Class | Enum

(第二行是输出,它在调试器/即时窗口中与通用Enum.ToString()输出不同。)

答案 3 :(得分:4)

为什么需要清单?一切都已存储在旗帜中:

[Flags]
enum Roles
{
    Read = 0x1,
    Write = 0x2,
    Delete = 0x4,
}

然后分配角色:

var roles = Roles.Read | Roles.Write;

无论何时你需要检查一个给定的角色是否已经不需要查看列表,只需查看角色枚举:

if ((roles & Roles.Read) == Roles.Read)
{
    // The user has read permission
}
if ((roles & Roles.Write) == Roles.Write)
{
    // The user has write permission
}

答案 4 :(得分:1)

List<string> GetRoleNames(Roles roles) =>
    Enum.GetValues(typeof(Roles))
        .Cast<Roles>()
        .Where(role => roles.HasFlag(role))
        .Select(role => role.ToString())
        .ToList();

void TestRoleSelection()
{
    var selectedRoles = (Roles)6;
    var roleNames = GetRoleNames(selectedRoles);
    Console.WriteLine(string.Join(",", roleNames));
    // Output: Admin,User
}

[Flags]
enum Roles
{
    SuperAdmin = 1,
    Admin = 2,
    User = 4,
    Anonymous = 8
}

答案 5 :(得分:0)

对Mick的回答类似,但将操作放入扩展名和修正 /中(从拆分中清除多余的空格字符)。

如果枚举中包含_,则代码也会将其更改为空格。

public static class EnumExtensions
{  
    // Take anded flag enum and extract the cleaned string values.
    public static List<string> ToComparableStrings(this Enum eNum)
        =>  eNum.ToString()
                .Split(',')
                .Select(str => str.ToCleanString())
                .ToList();

    // Take an individual enum and report the textual value.
    public static string ToComparableString(this Enum eNum)
        => eNum.ToString()
               .ToCleanString();

    // Remove any spaces due to split and if `_` found change it to space.
    public static string ToCleanString(this string str)
        => str.Replace(" ", string.Empty)
              .Replace('_', ' ');
}

用法

var single   = PivotFilter.Dollars_Only;
var multiple = PivotFilter.Dollars_Only | PivotFilter.Non_Productive;

                                // These calls return:
single.ToComparableString()     // "Dollars Only"
multiple.ToComparableString()   // "Non Productive,Dollars Only"
multiple.ToComparableStrings()  // List<string>() { "Non Productive", "Dollars Only" }

使用枚举

[Flags]
// Define other methods, classes and namespaces here
public enum PivotFilter
{
    Agency = 1,
    Regular = 2,
    Overtime = 4,
    Non_Productive = 8,
    Dollars_Only = 16,
    Ignore = 32
}