【问题标题】:Trying to parse a flag enum to string试图将标志枚举解析为字符串
【发布时间】:2014-10-01 20:15:53
【问题描述】:

我有一个“许可证”类,它是一堆枚举标志的集合,如下所示:

Public class License
{
    UsageType Usage { get; set; }
    PlatformType Platform { get; set; }

    public enum UsageType { read = 1, write = 2, wipe = 4, all = 7 }
    public enum PlatformType { windows = 1, linux = 2, ios = 4, all = 7 }

    etc...
}

关键是同一类别的各种标志可以通过“或”运算来形成用户可以使用所述许可证执行的操作的概要文件。现在我正在尝试以人性化的方式显示“使用”和“平台”的值,例如 if Usage == UsageType.read | UsageType.write 那么它应该被解析为“读,写”。

我通过测试每个标志的值并将每个标志的 enumitem.ToString() 附加到字符串中,成功地使用了单个枚举类型。由于我有很多这些枚举和值,我想提出一种更通用的方法。

我想出了这个(下),但由于我对 c# 中的模板函数不是很熟悉,所以我不知道为什么这不起作用,但至少它应该说明我的意思:

private string parseEnum<T>(T value)
{
    string ret = "";
    foreach (var ei in (T[])Enum.GetValues(typeof(T)))
    {
        if (value.HasFlag(ei)) ret += ei.ToString() + ", ";
    }
    ret = ret.substring(0, ret.Length-1);
    return ret;
}

这是说 T 不包含“HasFlag”的定义,但现在如果它不知道 T 是什么,怎么可能呢?

【问题讨论】:

标签: c# parsing generics enums


【解决方案1】:

您应该使用FlagsAttribute,这会使内置的ToStringEnum.Parse 方法按照您想要的方式工作。另请注意,约定是标记枚举名称should be plural,例如UsageTypes 而不是 UsageType

[Flags]
public enum UsageTypes { Read = 1, Write = 2, Wipe = 4, All = 7 }
[Flags]
public enum PlatformTypes { Windows = 1, Linux = 2, iOs = 4, All = 7 }

var e1 = License.UsageTypes.Read | License.UsageTypes.Write;
var s = e1.ToString();
Debug.Assert(s == "Read, Write");
var e2 = (License.UsageTypes)Enum.Parse(typeof(License.UsageTypes), s);
Debug.Assert(e1 == e2);

【讨论】:

  • 谈命名约定,枚举字段should be in Pascal Case
  • 如果e1 = License.UsageTypes.All s == "All" 而不是 "Read, Write, Wipe" 则不起作用
  • 我认为这是 Tim 的意图,因此他将 All 的值设置为 7 而不是 8(这会使它成为唯一值,而不是累积值)。它代表了前 3 个选项的组合。 (UsageTypes.Read | UsageTypes.Write | UsageTypes.Wipe).ToString("F") 计算结果为 "All"。如果您希望始终看到选定的各个选项,只需从枚举中删除 All
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多