C# 重构枚举以包含数值的简单方法?

C# 重构枚举以包含数值的简单方法?,c#,xml,enums,refactoring,automated-refactoring,C#,Xml,Enums,Refactoring,Automated Refactoring,我有一堆从XSD生成的枚举。它们的格式如下(带有名称的枚举,但不是数值): 我意识到,我可能可以通过创建一个方法来解决这个问题,该方法将每条数据的int值附加到字符串项,并使用结果名称将其解析为枚举,但这有两个缺点: 感觉像一个肮脏的黑客 对于像MyEnum.Item02和MyOtherEnum.Item002 它不允许我使用系统外定义的整数值引用枚举值(即,这不符合枚举所基于的XSD中的规则) 即使有200个项目,我想现在你也可以(很可能)手工完成,或者用C#编写一个程序来完成 不过,作为将

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

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

  • 感觉像一个肮脏的黑客
  • 对于像
    MyEnum.Item02
    MyOtherEnum.Item002
  • 它不允许我使用系统外定义的整数值引用枚举值(即,这不符合枚举所基于的XSD中的规则)
即使有200个项目,我想现在你也可以(很可能)手工完成,或者用C#编写一个程序来完成

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

  • 打开源文件。确保每个枚举值的声明相同;特别是在最后一个逗号后加逗号
  • 按Ctrl+H以显示搜索和替换UI
  • 输入
    Item(\d+),
    作为要查找的文本,输入
    Item$1=$1,
    作为替换文本
  • 确保范围设置为“当前文档”
  • 按Alt+A。这将替换文件中的所有匹配项
  • 这实际上足以让代码按照您的需要编译。但您可能希望删除前导
    0
    数字。您可以再次使用“搜索和替换”来执行此操作:

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

    因此,如果您想创建转换所需的字典(您不想一直检查属性本身,因为反射速度很慢),可以通过反射枚举枚举枚举类型,获取每个值的属性,解析
    XmlEnumAttribute.Name
    属性中的字符串,并使用它来创建字典条目,即在
    字典
    字典
    中,以便于在两个方向上进行转换。

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

    在我生成的文件中,大多数枚举都在同一个文件中,对于其中一些枚举,值已经被替换。因此,运行“全部替换”过程将导致其他问题

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

    F3(查找下一个)可以在正常搜索中使用,以跳过不应更改的匹配

    前导零

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

    谢谢彼得,这是一个很好的答案,正是我想要的。到现在为止,我已经手工替换了一些最重要和最常用的枚举,但仍然有一些非常长的枚举。你帮我省了很多工作。
    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,
    }
    
    var myEnumValue = (MyEnum) integerFromDb;