【问题标题】:Convert enum with duplicate underlying value to dictionary of string and enum将具有重复基础值的枚举转换为字符串和枚举字典
【发布时间】:2021-01-22 11:46:36
【问题描述】:

我正在处理一个需要加载 JSON 配置文件、使用 Newtonsoft.JSON 解析并提取值的项目。一些 key-value-paris 必须映射到 Enum,结果应该是 Dictionary<string, enumType>。这些枚举之一是System.Drawing.RotateFlipType。但是因为这个枚举有 16 个成员,其中 8 个成员与另一个成员共享基础值,ToDictionary 方法会抛出一个 System.ArgumentException,因为“已经有一个元素具有相同的键”。

目前我正在使用以下代码:

var rotationTypesDict = Enum
                        .GetValues(typeof(RotateFlipType))
                        .Cast<RotateFlipType>()
                        .ToDictionary(x => x.ToString(), x => x);

这里的问题是 Linq 查询的返回类型:Dictionary&lt;string, RotateFlipType&gt;。由于 ToString() 应用于 RotationFlipType 且基础值为 0,因此仅解析“RotateNoneFlipNone”,即使“Rotate180FlipXY”也具有基础值“0”。所以我想知道有没有机会完成这项工作。

我还尝试了另一种方式来使用Enum.GetNames()ToDictionary() ToDictionary 元节点将键作为字符串返回(如预期的那样),但值与以前存在相同的问题。当使用字符串“RotateNoneFlipNone”来查找基础值时,它得到的值是 0,这让我得到了 RotationFlipType.RotateNoneFlipNone 成员。完美的!但是当使用字符串“Rotate180FlipXY”时,基础值也是“0”,这给了我成员RotationFlipType.RotateNoneFlipNone,在这种情况下是错误的。 (错误,因为如果在配置文件中用户想要使用 RotationFlipType "Rotate180FlipXY" 那么程序在字典中搜索这个值并没有找到它。)

编辑:按照 JonasH 的要求,我尝试解释我想要什么。 目标是获取 Dictionary ,其中键是成员的名称,值等于成员的基础值。 这是必需的,因为配置文件是从另一个程序中导出的,该程序在 Combobox 中显示可能的 RotationFlipTypes。由于要导出的值是通过从组合框中调用SelectedItem.ToString() 来检索的,因此如果我选择 RotationFlipType“Rotate180FlipXY”,它在技术上与 RotationFlipType“RotateNoneFlipNone”相同,但配置文件将包含“Rotate180FlipXY”。所以在读取和解析config 文件并查找“Rotate180FlipXY”不会有任何结果,因为当我只包含具有唯一基础值的条目时,成员“RotateNoneFlipNone”和“Rotate180FlipXY”将被压缩为“RotateNoneFlipNone”。对于单线

【问题讨论】:

  • 你将它们分组并返回Dictionary&lt;string, IList&lt;RotateFlipType&gt;&gt;
  • 我不太清楚这里的实际目标是什么。如果RotateNoneFlipNoneRotate180FlipXY 具有相同的值,则它们是相同的。如果你不希望它们是同一个东西,它们应该有不同的值。

标签: c# dictionary enums


【解决方案1】:

由于GetNamesGetValues 总是以相同的顺序返回,您可以使用Zip 将它们连接在一起。让我们把它变成一个通用函数来结束它:

public Dictionary<string, T> GetEnumDict<T>() where T : struct //, System.Enum if on C# 7.3
{
    return Enum.GetNames(typeof(T))
        .Zip(Enum.GetValues(typeof(T)),
            (n, v) => (n, (T)v))
        .ToDictionary(
            nv => nv.n,
            nv => nv.v
    );
}

var rotationTypesDict = GetEnumDict<RotateFlipType>();

【讨论】:

    【解决方案2】:

    这应该可行:

    var rotationTypesDict = Enum
        .GetNames(typeof(RotateFlipType))
        .ToDictionary(
            x => x,
            x => Enum.TryParse(x, out RotateFlipType y)
                ? y
                : throw new InvalidEnumArgumentException("Should never happen."));
    

    【讨论】:

      猜你喜欢
      • 2012-12-07
      • 1970-01-01
      • 2019-02-21
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多