一种重构枚举以包含数值的简单方法?

An easy way to refactor Enums to include numeric value?

我有一堆从 XSD 生成的枚举。它们具有如下格式(带名称但不带数值的枚举):

public enum MyEnum
{        
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("001")]
    Item001,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("002")]
    Item002,

    .... // etc.

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("199")]
    Item199,
}

我想要的是一种重构这些的简单方法,如下所示:

public enum MyEnum
{ 
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("001")]
    Item001 = 1,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("002")]
    Item002 = 2,

    .... // etc.

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("199")]
    Item199 = 199,
}

我需要它来将整数值(来自配置文件或数据库)解析为枚举值。请注意,所需的 int 值可以在 XmlEnumAttribute 和枚举值名称本身中找到 - 只是不是数字值。

任何快速执行此重构的想法都将不胜感激。

示例和额外背景信息:

我想做:

var myEnumValue = (MyEnum) integerFromDb;

我意识到我可能可以通过创建一个方法来解决这个问题,该方法将每条数据的 int 值附加到字符串 Item,并使用结果名称将其解析为枚举,但是几个弱点:

即使有 200 个项目,我猜你现在可以(并且很可能已经)手工完成,或者用 C# 编写程序来完成。

虽然为了将来参考,您可以使用 Visual Studio 的搜索和替换功能来执行此操作而不会有太多麻烦(注意......我在这里假设 VS2013,它使用标准的 .NET 正则表达式语法; 早期版本的 VS 也可以做到这一点,但它们使用自定义正则表达式语法,如果需要你可以自己查找):

  1. 打开源文件。确保每个枚举值声明相同;特别是,即使在最后一个之后也要加一个逗号。
  2. Ctrl+H显示搜索替换UI
  3. 输入 Item(\d+), 作为要查找的文本,输入 Item = , 作为替换文本。
  4. 确保范围设置为 "Current Document"。
  5. Alt+A。这将替换文件中的所有匹配项。

这实际上足以让代码按照您的需要进行编译。但您可能更愿意删除前导 0 数字。您可以再次使用搜索和替换来做到这一点:

  1. 输入 = 0 作为要查找的文本,输入 = 作为替换文本。
  2. Alt+A两次(因为你最多有两个前导零)

最后:就您仅在 运行 时间内处理它的想法而言,考虑到对名称的确切格式的依赖,通过值名称进行转换确实存在潜在问题。但请注意,您在 [XmlEnum] 属性中有一个真正的可解析整数。

因此,如果您想为转换创建必要的字典(您不想继续检查属性本身,因为反射 ),您可以枚举枚举通过反射输入,获取每个值的属性,解析在 XmlEnumAttribute.Name 属性 中找到的字符串,并使用它来创建字典条目,即在 Dictionary<int, MyEnum>Dictionary<MyEnum, int> 中以促进任一方向的转换。

我已经接受了 ,但我想在这里进一步扩展它,因为我使用了几个变体:

在我生成的文件中,大多数枚举都在同一个文件中,其中一些枚举的值已经被替换。 运行 "Replace All" 过程因此会导致其他问题。

替换下一个
因此,我没有使用 Alt + A (replace all) 来替换所有匹配项,而是使用 Alt + R (replace next) 重复循环并仅替换那些必要的匹配项。这让我可以快速遍历所有代码,而不会弄乱已经修复的代码。

F3查找下一个)可以像在普通搜索中一样使用,跳过不应更改的匹配项。

前导零
我不想删除例如 0 Item010 = 0,这将是无效的,所以我改用以下搜索词:= 0\d,它只找到 leading 零(即零后跟另一个数字)。