如何提取通用/相似的代码块以在Visual Studio C#中运行 [英] How to extract common/similar code blocks to function in Visual Studio C#

查看:248
本文介绍了如何提取通用/相似的代码块以在Visual Studio C#中运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想选择代码,例如

  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)

etc。



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



我认为我也可以通过正则表达式实现这一点,但是我还没有开悟正则表达式。我该怎么做?

解决方案

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




  • 提取方法

  • 引入参数

  • 使用模式搜索



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







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



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



    结果:

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

    }


  2. 在函数中选择一个 myEnum.firstThing,介绍参数 Ctrl + R P )或右键单击重构引入参数



    向导很容易解释:)



    结果:

      GroupCommonStuf(myEnum类型)
    {
    doSomething(type)
    doSomethingElse(type)
    evenMoreStuff(type)
    }


  3. ReSharper→查找使用模式搜索(单击替换选项卡)



    选择一个未触及的违规代码块,右键单击*→查找相似代码


  4. 单击添加PlaceHolder→类型 =参数→名称 =枚举


  5. 键入以下内容:





    结果:



    使用上述模式脚本代码块可以tch:

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

    将替换为

      GroupCommonStuf(myEnum.firstThing)

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


有关此处发生的情况的一些解释



简而言之,ReSharper会在()之间找到任何参数,并将其存储在变量枚举中(名称实际上并没有物)。然后在变量出现在替换块中的任何位置插入参数字符串。



有不同的



引入参数→查找替换带有/不带有将变量升级为参数



搜索方式模式→
这对我来说显然是一个艰难的选择,我不想特别探索三个选项,我的猜测通常是需要更多时间,然后才能手动进行更改:




  • 非常聪明的正则表达式(在Visual Studio中可能很烦人)

  • 带有聪明sed的Bash脚本(轻微 仅在Visual Studio中进行正则表达式改进,但仍然很困难)

  • 编写自己的解析器????????????????


I want to select code, e.g.

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

and convert it to a function

GroupCommonStuf(myEnum.firstThing)

which would look like:

GroupCommonStuff(myEnum id)
{
  doSomething(id)
  doSomethingElse(id)
  evenMoreStuff(id)
}

Preferably it would catch any code that is:

doSomething(myEnum.secondThing)
doSomethingElse(myEnum.secondThing)
evenMoreStuff(myEnum.secondThing)

and convert it to

GroupCommonStuf(myEnum.secondThing)

etc.

I have ReSharper installed. But the extract method in ReSharper seems to only extract the code block I select. It doesn't propagate it other "similar code", which I am sure Eclipse does for C++ and Java.

I assume I could also achieve this through regular expressions, but I am not regular expression enlightened yet. How can I do this?

解决方案

This is possible in three steps using three useful ReSharper tools:

  • Extract To Method
  • Introduce Parameter
  • Search With Pattern

Possible alternatives without ReSharper are at the bottom


  1. Select one offending code block, Extract To Method

    (Ctrl + R, M)*** or right clickRefactorExtractMethod)

    Result:

    GroupCommonStuf()
    {
        doSomething(myEnum.firstThing)
        doSomethingElse(myEnum.firstThing)
        evenMoreStuff(myEnum.firstThing)
    
    }
    

  2. Select one "myEnum.firstThing" within the function, Introduce Parameter (Ctrl + R, P) or right clickRefactorIntroduce parameter

    The wizard is pretty self explanatory :)

    Result:

    GroupCommonStuf(myEnum type)
    {
        doSomething(type)
        doSomethingElse(type)
        evenMoreStuff(type)
    }
    

  3. ReSharper → FindSearch With Pattern (click replace tab)

    OR Select an untouched offending code block, Right click* → Find Similar Code

  4. Click Add PlaceHolder→ "Type" = Arguments → "Name"=enumeration

  5. Type the following:

    Result:

    Using the above pattern script code blocks that match:

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

    will be replaced with

    GroupCommonStuf(myEnum.firstThing)
    

    The same for any variation of the enum :).

Some Explanation On What's Going On Here

In short, ReSharper is finding any arguments between ( ) and storing them in the variable "enumeration" (the name doesn't actually matter). Then inserting that string of arguments anywhere the variable appears in the replace block.

There are different placeholders that do different things and it's important to use the right one. The "type" placeholder even supports regular expressions which makes it incredibly powerful.

You could simply type $enumeration$ in this case because the default placeholder is "arguments". However I would advise getting in the habit of using "add placeholder" as it will be clearer when you do more complex patterns. It's important that you know it's not just "put strings here into variable".

To explain this better, consider this example, say you had the following code dotted around:

... = GetGraphic(Graphics.First).ShapeArray[index].ShapeColour
... = GetGraphic(Graphics.Second).ShapeArray[index].ShapeSize
... = GetGraphic(Graphics.First).ShapeArray[index].ShapeSize

And you had decided to replace all of these with code more akin to

... = GetShapeColour(Graphics.First, index);
... = GetShapeSize(Graphics.Second, index);
... = GetShapeSize(Graphics.First, index);

By using the correct place holders you can do this with one search and replace:

  • $args$ (an argument placeholder) takes care of moving whatever the parameters is for you, in this case its just one, but it could be several.
  • $variableOfArray$ (A type place holder, with regex set to Shape*) takes care of moving the ShapeColour, ShapeSize "variable type" names

If you had used "argument placeholder" for "variableOfArray" Resharper would have said it couldn't find any occurrences of that pattern because there was no such thing as GetGraphic( .. ).ShapeArray[index].( .. ).


Possible Work-arounds without ReSharper:

Extract To Method → Extract Method Refactoring

Introduce Parameter → "find replace" with/without Promote Variable To Parameter

Search With Pattern → This is clearly the hard one to me there are three options that I wouldn't particularly want to explore and my guess would be would generally require more time then it would to do the changes manually:

  • VERY clever regular expression (this could be annoying within Visual Studio itself)
  • Bash scripts with clever sed (slight improvement on just regexing within Visual Studio, but still hard)
  • Writing your own parser???When all else fails...to the code!

这篇关于如何提取通用/相似的代码块以在Visual Studio C#中运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆