重构Enums以包含数值的简单方法?

时间:2015-01-12 14:15:02

标签: c# xml enums refactoring automated-refactoring

我有一堆从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,并使用生成的名称将其解析为枚举,但是它有一对弱点:

  • 感觉就像一个肮脏的黑客
  • 可能无法正常使用MyEnum.Item02MyOtherEnum.Item002
  • 等名称
  • 它不允许我使用在我的系统之外定义的整数值来引用枚举值(即,这不符合我的枚举所基于的XSD中的规则)。

2 个答案:

答案 0 :(得分:2)

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

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

  1. 打开源文件。确保每个枚举值都被声明为相同;尤其是在最后一个之后加上一个逗号。
  2. Ctrl + H 显示搜索和替换用户界面
  3. 输入Item(\d+),作为要查找的文字,并输入Item$1 = $1,作为替换文字。
  4. 确保范围设置为“当前文档”。
  5. Alt + A 。这将替换文件中的所有匹配项。
  6. 这实际上足以让代码按需要编译。但您可能更愿意删除前导0位数。您可以再次使用搜索和替换来执行此操作:

    1. 输入= 0作为要查找的文字,并输入=作为替换文字。
    2. 按两次 Alt + A (因为您最多有两个前导零)
    3. 最后:就您在运行时处理它的想法而言,考虑到对名称的确切格式的依赖性,通过值名称进行转换确实可能存在问题。但请注意,[XmlEnum]属性中有一个真正的可解析整数。

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

答案 1 :(得分:1)

我已经接受了the answer by Peter Duniho,但我想在这里进一步扩展,因为我使用了几种变体:

在我生成的文件中,大多数枚举都在同一个文件中,对于其中一些枚举,则值已被替换。运行&#34;全部替换&#34;因此,程序会引起其他问题。

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

F3 查找下一个)可用于普通搜索,以跳过不应更改的匹配。

前导零
我并不想将0转移到例如0 Item010 = 0,这将是无效的,因此我使用了以下搜索字词:= 0\d,它只找到前导零(即零后跟另一个数字)。