远离主要构造者

时间:2014-12-12 18:29:09

标签: c# roslyn c#-6.0 primary-constructor

Visual Studio 2013的C#6预览版支持主要构造函数,该团队已决定不会将其纳入最终版本。不幸的是,我的团队使用主要构造函数实现了200多个类。

我们现在正在寻找最直接的途径来迁移我们的来源。由于这是一次性的事情,一个神奇的正则表达式替换字符串或hacky解析器将起作用。

在我花大量时间写这样一只野兽之前,那里有没有人已经做过这个或知道更好的方法?

2 个答案:

答案 0 :(得分:6)

正如我在评论中建议的那样,您可以使用 知道主要构造函数的Roslyn版本将代码解析为语法树,然后修改该语法树以使用“普通”构造函数代替。您还需要将使用主构造函数参数的所有初始化程序放入新构造函数中。请注意。

我怀疑编写代码会花费 me 至少两三个小时,很可能更多 - 而我可以在相同的时间内手动完成相当多的课程。自动化很棒,但有时候最快的解决方案就是手工完成......即使是200个类手动也可能更快,你可以明确地并行化多个人的工作。

答案 1 :(得分:3)

(\{\s*)(\w*\s*?=\s*?\w*\s*?;\s*?)*?(public\s*\w*\s*)(\w*)(\s*?{\s*?get;\s*?\})(\s*?=\s*?\w*;\s*)
\1\2\4\5

一些答案​​:第一个用简单的正则表达式找到并替换你需要重复几次:

  1. 正则表达式:几行解释然后是实际的正则表达式字符串和替换字符串:

    一个。在正则表达式中,首先匹配您要查找的完整字符串(在您的情况下是主要构造函数)。不难做到:搜索大括号,单词public,然后是两个单词和一个等号等。根据这个发现的每个文本称为匹配。

    湾有时,您正在寻找的文本中可能存在重复的序列。 (在您的情况下:参数在每行中定义一行)。为此,您只需将预期序列标记为一个组,方法是用括号括起来。

    ℃。然后,您需要标记所找到的内容的不同部分,以便您可以使用它们或在更正后的文本中替换它们。这些部分也称为“组”实际上是“捕获组”。再次简单地用括号括起部分。 在您的情况下,您将保留第一个捕获的组(大括号)和属性的名称及其对参数的赋值。

    d。这是正则表达式:

    (\{\s*)(\w*\s*?=\s*?\w*\s*?;\s*?)*?(public\s*\w*\s*)(\w*)(\s*?{\s*?get;\s*?})(\s*?=\s*?\w*;\s*)
    
    1. ( 
          // ---- Capture1 -----
          {         
              // code: \{\s*? 
              // explained: curley bracket followed by possible whitespace
       ) 
    
    2. ( - Capture2  - previously corrected text 
          // - possible multiple lines of 'corrected' non-primary-constructors 
          // created during the find-replace process previously, 
    
          Propname = paramname;  // word,  equals-sign, word, semicolon 
          // code:  \w*\s*?=\s*?\w*\s*?;\s*?
          // explained:   \w - any alphanumeric, \s - any whitespace
          //              * - one or more times, *? - 0 or more times 
       )*?  
          // code: )*?
          // explained:  this group can be repeated zero or more times 
          // in other words it may not be found at all. 
          // These text lines are created during the recursive replacement process...
    
    3. ( 
          //  ----Capture 3-----
          // The first line of a primary constructor: 
          public type
          // code: public\s*\w*\s*  
          // explained: the word 'public' and then another word (and [whitespace]) 
        )
    
    4. (
        // ----- capture 4 -----
        Propname
         // code: \w@  
         // explained:  any amount of alphanumeric letters
       )
    
    5. (
         // ---- capture 5 ----
         { get; }
         // code: \s*?{\s*?get;\s*?\}
       )
    
    6. (
        // ---- capture 6 ----
         = propname; 
        code: \s*?=\s*?\w*;\s*
        explained: by now you should get it. 
    
  2. 替换字符串是

    \1\2\4\6
    

    这留下:

    { 
        [old corrected code] 
        [new corrected line]
        possible remaining lines to be corrected. 
    
    1. Notepad ++ 10分钟试错。我保证不会超过你。

    2. Visual Studio 2014 重构。但 一个。您必须将其安装在单独的VM或PC上。 MS警告您不要将其与现有代码并排安装。 湾我不确定重构是否正常工作。 [Here's an article about it][1]

    3. Visual Studio宏。我知道,我知道,它们早已不复存在,但至少有两个插件可以替代它们,也许更多。我在this SO (StackOverflow) discussion上了解了它们。 (他们提供了一些其他选择)这里:

    4. Visual Commander - 免费开源Visual Studio宏运行程序加载项
    5. VSScript - A Visual Studio add-on:费用为50美元!!

    6. 尝试Automatic Regexp by example:您可以给出几个代码示例,其中突出显示预期结果是什么,然后是相同(或其他)代码,其中突出显示的不是预期结果。然后等待它运行示例并为您提供一些正则表达式代码。

      //以下代码(来自http://odetocode.com/blogs/scott/archive/2014/08/14/c-6-0-features-part-ii-primary-constructors.aspx

      public struct Money(字符串货币,小数) {     public string Currency {get; } =货币;     公共小数金额{get; } =金额; } //我得到的结果如下:{++ \ w \ w [^ r-u] [^ _] ++ | [^ {] ++(?= {\ w ++ =)

    7. 在这个伟大的网站上使用正则表达式:https://www.regex101.com/

      // I first tried: \{\s*((public\s*\w*\s*)\w*(\s*?{\s*?get;\s*?})\s*?=\s*?\w*;\s*)*\}
      
    8. 主构造函数行的重复序列(“重复捕获组”)仅捕获最后一个。

      1. 按照here in another StackOverflow (see accepted answer)
      2. 说明,将{#code}与regex.captures一起使用