【问题标题】:An easy way to refactor Enums to include numeric value?重构枚举以包含数值的简单方法?
【发布时间】:2015-01-13 19:10:00
【问题描述】:

我有一堆从 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 中的规则)。

【问题讨论】:

    标签: c# xml enums refactoring automated-refactoring


    【解决方案1】:

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

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

    1. 打开您的源文件。确保每个枚举值都以相同的方式声明;尤其是在最后一个逗号之后。
    2. Ctrl+H 显示搜索和替换 UI
    3. 输入 Item(\d+), 作为要查找的文本,输入 Item$1 = $1, 作为替换文本。
    4. 确保范围设置为“当前文档”。
    5. Alt+A。这将替换文件中的所有匹配项。

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

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

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

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

    【讨论】:

    • 谢谢彼得,这是一个很好的答案,正是我想要的。我现在已经手动替换了一些最重要和最常用的枚举,但我还剩下一些很长的枚举。你为我节省了很多工作。
    【解决方案2】:

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

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

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

    F3 (Find Next) 可以像在正常搜索中一样使用,以跳过不应更改的匹配项。

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

    【讨论】:

      猜你喜欢
      • 2014-03-08
      • 2023-03-23
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多