vb.net - 将所有变量更改为显式类型

标签 vb.net visual-studio automation

(无意对编码风格发起宗教 war ,我只需要解决手头的问题)

我刚刚被要求更改整个解决方案中的所有变量声明以使用显式类型,即:

Dim Result = 3 + 5

应转换为:
Dim Result As Integer = 3 + 5

显然,这不能通过查找/替换甚至使用正则表达式来完成。我想到的另外两种可能性是:
  • Resharper:我刚刚发现它只能用于 C#,不能用于 VB.NET。
  • 宏:自 VS2012 以来已被删除(对我来说是个新闻)。

  • 有没有其他方法可以使这项乏味的工作自动化?该解决方案包含数十万行代码,因此无法手动完成。

    这是针对 VS2017 社区的。

    最佳答案

    最后,我能够使用多种技术解决我的问题。这是我所做的,以防万一这有助于其他人:

  • 我与有关方面进行了交谈,我们同意在以下场景中不需要使用显式类型:
    Dim X1 = 45 + 43 'Type can be inferred by the reader easily
    Dim X2 = DirectCast(obj, DataReader) 'Type explicitly mentioned on RHS        
    Dim X3 = New SomeClass() 'Type explicitly mentioned on RHS
    
  • 因此,真正可读性较差且需要显式键入的情况如下:
    Dim X4 = SomeMethod() 'Cannot infer X4's type without peeking or using Go To Definition
    
  • 然后我使用以下 RegEx 来定位所有此类实例:
    Dim \w+ = (?!(New|\d|"|DirectCast))
    
  • 我只剩下几百个实例,但单独检查它们仍然是一项艰巨的任务,找到 RHS 方法的类型,然后在 LHS 上输入它。所以我搜索了 VS 扩展,找到了 Visual Commander这允许我们在 C# 或 VB.NET 中编写、猜测什么宏,并使用 Roslyn API 以我们想要的任何方式操作代码元素。所以我安装了它,在玩了一段时间后,我能够编写以下宏来提取 RHS 方法的返回类型,然后将其注入(inject) LHS:
    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.Text;
    using System.Linq;
    using Microsoft.CodeAnalysis.VisualBasic;
    using Microsoft.CodeAnalysis.VisualBasic.Syntax;
    
    public class C : VisualCommanderExt.ICommand
    {
      public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
      {
        serviceProvider = package as System.IServiceProvider;
        Microsoft.VisualStudio.Text.Editor.IWpfTextView textView = GetTextView();
    
        Microsoft.VisualStudio.Text.SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;
        Microsoft.CodeAnalysis.Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
        Microsoft.CodeAnalysis.VisualBasic.Syntax.LocalDeclarationStatementSyntax invocationExpressionNode =
            document.GetSyntaxRootAsync().Result.FindToken(caretPosition).Parent.AncestorsAndSelf().
                OfType<Microsoft.CodeAnalysis.VisualBasic.Syntax.LocalDeclarationStatementSyntax>().FirstOrDefault();
    
        if (invocationExpressionNode != null)
        {
          Microsoft.CodeAnalysis.SemanticModel semanticModel = document.GetSemanticModelAsync().Result;
    
          var VD = invocationExpressionNode.ChildNodes().FirstOrDefault(c => c.IsKind(SyntaxKind.VariableDeclarator));
    
          if (VD != null)
          {
            var EV = VD.ChildNodes().FirstOrDefault(c => c.IsKind(SyntaxKind.EqualsValue) || c.IsKind(SyntaxKind.EqualsExpression));
    
            if (EV != null)
            {
              object IE = EV.ChildNodes().FirstOrDefault(c => c.IsKind(SyntaxKind.InvocationExpression));
    
              if (IE != null)
              {
                Microsoft.CodeAnalysis.IMethodSymbol methodSymbol =
                  semanticModel.GetSymbolInfo((InvocationExpressionSyntax)IE).Symbol as Microsoft.CodeAnalysis.IMethodSymbol;
    
                string TypeName = methodSymbol.ReturnType.ToString();
                string ToInsert = " As " + TypeName;
                textView.TextBuffer.Insert(((InvocationExpressionSyntax)IE).SpanStart - 2, ToInsert);
              }
            }
          }
        }
      }
    
      private Microsoft.VisualStudio.Text.Editor.IWpfTextView GetTextView()
      {
        Microsoft.VisualStudio.TextManager.Interop.IVsTextManager textManager =
            (Microsoft.VisualStudio.TextManager.Interop.IVsTextManager)serviceProvider.GetService(
                typeof(Microsoft.VisualStudio.TextManager.Interop.SVsTextManager));
        Microsoft.VisualStudio.TextManager.Interop.IVsTextView textView;
        textManager.GetActiveView(1, null, out textView);
        return GetEditorAdaptersFactoryService().GetWpfTextView(textView);
      }
    
      private Microsoft.VisualStudio.Editor.IVsEditorAdaptersFactoryService GetEditorAdaptersFactoryService()
      {
        Microsoft.VisualStudio.ComponentModelHost.IComponentModel componentModel =
            (Microsoft.VisualStudio.ComponentModelHost.IComponentModel)serviceProvider.GetService(
                typeof(Microsoft.VisualStudio.ComponentModelHost.SComponentModel));
        return componentModel.GetService<Microsoft.VisualStudio.Editor.IVsEditorAdaptersFactoryService>();
      }
    
      private System.IServiceProvider serviceProvider;
    }
    
  • 这个脚本为我做了繁重的工作。然后我就可以将快捷键分配给 GoToFindResult1NextLocationGoToFindResult1PrevLocation命令并遍历查找结果,修复我需要的结果。
  • 通过循环遍历解决方案中的所有文件并自动修复所有这些行,可以改进此代码以提供更多自动化,但我认为对将要更改的行进行更多控制是明智的。

  • 最后,我能够在几分钟内解决解决方案中的所有问题。此外,我还学到了很多有关 Roslyn API 结构的知识。

    关于vb.net - 将所有变量更改为显式类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48202311/

    相关文章:

    C#登录系统,在将密码插入数据库之前需要帮助散列密码

    visual-studio - 为什么 "Namespace Provider"属性没有保存在给定子目录的项目文件中?

    java - 您可以根据自己的需要创建一个 TestNG Listener

    .net - 在 VB.NET 中使用 Yield 时出错 - 方法参数必须括在括号中

    .net - 如何在 Visual Basic 中使用 LINQ to Entities?

    c# - 如何使用Android向PC发送消息并实时接收

    c# - 为什么 Visual Studio 的智能感知不适用于派生类?

    java - 在 maven 构建中集成 yahoo smush.it 以进行图像压缩

    html - 编辑多个 HTML 文件

    vb.net - 从 SQL Server CE 检索记录 [这个星球上有人可以解决这个问题吗??]