c# - 如何提取通用/相似代码块以在 Visual Studio C# 中运行

标签 c# regex visual-studio-2012 resharper automated-refactoring

我想选择代码,例如

doSomething(myEnum.firstThing)
doSomethingElse(myEnum.firstThing)
evenMoreStuff(myEnum.firstThing)

并将其转换为函数
GroupCommonStuf(myEnum.firstThing)

这看起来像:
GroupCommonStuff(myEnum id)
{
  doSomething(id)
  doSomethingElse(id)
  evenMoreStuff(id)
}

最好它会捕获以下任何代码:
doSomething(myEnum.secondThing)
doSomethingElse(myEnum.secondThing)
evenMoreStuff(myEnum.secondThing)

并将其转换为
GroupCommonStuf(myEnum.secondThing)

等等。

我已经安装了 ReSharper。但是 ReSharper 中的 extract 方法似乎只提取了我选择的代码块。它不会传播其他“类似代码”,我确信 Eclipse 会为 C++ 和 Java 做这些。

我想我也可以通过正则表达式来实现这一点,但我还没有对正则表达式有所了解。我怎样才能做到这一点?

最佳答案

这可以通过三个有用的 ReSharper 工具分三个步骤实现:

  • 提取到方法
  • 引入参数
  • 搜索模式

  • 没有 ReSharper 的可能替代方案位于底部

  • 选择一个有问题的代码块,提取到方法

    (Ctrl + R, M)*** 或右键单击 → 重构 → 提取 → 方法)

    结果:
    GroupCommonStuf()
    {
        doSomething(myEnum.firstThing)
        doSomethingElse(myEnum.firstThing)
        evenMoreStuff(myEnum.firstThing)
    
    }
    
  • 在函数中选择一个“myEnum.firstThing”,引入参数 ( Ctrl + R, P ) 或右键单击 → 重构 → 引入参数

    该向导非常不言自明:)

    结果:
    GroupCommonStuf(myEnum type)
    {
        doSomething(type)
        doSomethingElse(type)
        evenMoreStuff(type)
    }
    
  • ReSharper → 查找 → 使用模式搜索(单击替换选项卡)

    选择一个未触及的违规代码块,右键单击* → 查找相似代码
  • 点击添加占位符→“类型”=参数→“名称”=枚举
  • 键入以下内容:

    Enter image description here

    结果:

    使用上述匹配的模式脚本代码块:
    doSomething(myEnum.firstThing);
    doSomethingElse(myEnum.firstThing);
    evenMoreStuff(myEnum.firstThing);
    

    将被替换为
    GroupCommonStuf(myEnum.firstThing)
    

    枚举的任何变体都相同:)。

  • 关于这里发生的事情的一些解释

    简而言之,ReSharper 正在查找 ( ) 之间的任何参数并将它们存储在 中。变量 “枚举”(名称实际上并不重要)。然后将该参数字符串插入到变量出现在替换 block 中的任何位置。

    有不同的placeholders做不同的事情,使用正确的事情很重要。 “类型”占位符甚至支持正则表达式,这使得它非常强大。

    在这种情况下,您可以简单地键入 $enumeration$,因为默认占位符是“arguments”。但是,我建议养成使用“添加占位符”的习惯,因为当您执行更复杂的模式时它会更清晰。重要的是您知道这不仅仅是“将字符串放入变量中”。

    为了更好地解释这一点,请考虑这个示例,假设您有以下代码:
    ... = GetGraphic(Graphics.First).ShapeArray[index].ShapeColour
    ... = GetGraphic(Graphics.Second).ShapeArray[index].ShapeSize
    ... = GetGraphic(Graphics.First).ShapeArray[index].ShapeSize
    

    你决定用更类似于的代码替换所有这些
    ... = GetShapeColour(Graphics.First, index);
    ... = GetShapeSize(Graphics.Second, index);
    ... = GetShapeSize(Graphics.First, index);
    

    通过使用正确的占位符,您可以通过一次搜索和替换来做到这一点:

    enter image description here
  • $args$(一个参数占位符)负责移动任何适合您的参数,在这种情况下它只是一个,但它可能是多个。
  • $variableOfArray$(类型占位符,正则表达式设置为 Shape*)负责移动 ShapeColour、ShapeSize “变量类型”名称

  • 如果您对“variableOfArray”使用了“参数占位符”,Resharper 会说它找不到该模式的任何出现,因为没有 GetGraphic(..).ShapeArray[index].(..) 这样的东西。

    不使用 ReSharper 的可能解决方法:

    提取到方法 → Extract Method Refactoring

    引入参数 → “查找替换”有/无 Promote Variable To Parameter

    搜索模式 →
    这对我来说显然是一个难题,我不想特别探索三个选项,我的猜测是通常需要更多时间,然后手动进行更改:
  • 非常聪明的正则表达式(这在 Visual Studio 本身中可能很烦人)
  • 使用巧妙的 sed 编写 Bash 脚本(仅在 Visual Studio 中进行正则表达式略有改进,但仍然很难)
  • 编写自己的解析器???当所有其他方法都失败时......代码!
  • 关于c# - 如何提取通用/相似代码块以在 Visual Studio C# 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26674797/

    相关文章:

    C++ 正则表达式子匹配未出现

    visual-studio-2012 - MvvMCross 3.0.6 Nuget软件包安装问题

    c# - 从 WaveStream 将 2 channel 样本读入数组的最简单方法

    c# - List<T> 中的最大项目数是多少?

    javascript - SWIFT BIC 的正则表达式

    javascript - 用于验证国民保险号码的正则表达式

    c# - DotNetOpenAuth 在修改后编译但在运行示例项目时抛出运行时异常

    linux - Visual Studio 2012负载测试可以捕获Linux服务器和Oracle数据库的性能计数器吗?

    c# - 单个整数的 Web API ResponseType

    c# - 如何让我的文件读取类返回一个 IEnumerable<byte[]> 对象