【问题标题】:Is there any function or tool (free) to auto complete any .Net type name to fully qualified one?是否有任何功能或工具(免费)可以将任何 .Net 类型名称自动完成为完全限定的名称?
【发布时间】:2011-06-30 09:23:51
【问题描述】:

我在 Visual Studio 2010 中使用 VB.NET。是否有任何功能或工具可以自动完成任何 .Net 类型名称以完全限定?

我的意思是实际上将源代码从简写更改为完全限定名称的工具/功能,如下所示:

StringSystem.String

Process.Start 到这个System.Diagnostics.Process.Start

更新:

感谢 ReSharper 的建议。但 我不准备买它或奖励 商业产品的赏金 建议。 对此感到抱歉。我应该 把我的问题说清楚 要求。我已经尝试过 ReSharper 在问这个问题之前。

【问题讨论】:

  • 您为什么要这样做?它使代码不可读。
  • @Daniel Hilgarth:通常我会打印出任何有问题的代码部分。完全限定名称对我很有帮助
  • 当存在潜在的命名空间冲突时,我可以看到这会有所帮助。 Rectangle 是我想到最多的一个,似乎每个图书馆都有一个。
  • @Dee Jay,在您进行编辑之前,您没有询问 免费 工具。 R# 为生产力做了很多工作,恕我直言,它真的物有所值;如果您将其用于开源项目,您可以尝试申请免费的开源使用许可证。

标签: c# .net vb.net visual-studio-2010 .net-4.0


【解决方案1】:

Resharper 能够做到这一点。

虽然 Resharper 不是免费的,但绝对值得购买。一旦开始使用 Resharper,没有它您将无法继续。

下面一步一步显示,因为这不是很简单:

  1. 下载并安装 Resharper。

  2. 打开VS并进入菜单Rehsarper => Options => Languages => C# => Namespace Import。选择Use fully qualified names。默认选择Insert using directives when necessary

    从现在开始,每当您使用Alt+Enter 解析命名空间时,Resharper 都会解析完全限定的。

  3. 转到Rehsarper => Options => Tools => Code cleanup。点击Add 按钮添加新的清理配置文件。为新配置文件命名,例如Namespaces Reformat。检查Optimizing using directives 复选框。

  4. 右键单击项目并选择Cleanup Code...,或使用快捷方式Ctrl+E, Ctrl+C。选择之前创建的配置文件并点击Run 按钮。


测试

原码:

using System;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Test");
        }
    }
}

结果代码:

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("Test");
        }
    }
}

【讨论】:

  • 我同意 JetBrains 帮助中的说明不如您的准确,为此 +1。基本上,我的观点是,在这个特定工具中第一个提出这个功能的人会很高兴。无论如何,感谢您的讨论。
【解决方案2】:

这是一个适用于 C# 代码的宏。

当我在 VB .Net 项目上对其进行测试时,它不适用于程序集引用中的类型。似乎 VB.Net 的项目代码模型不包括外部类型。

无论如何,我在此处包含代码。也许其他人知道如何为 VB 做到这一点


首先我们需要一个查找当前上下文的函数

Private Function FindCodeElement(ByVal caretPosition As TextPoint, ByVal elems As CodeElements) As CodeElement
    If elems Is Nothing Then Return Nothing
    Return elems.Cast(Of CodeElement) _
                .Where(Function(x) x.StartPoint.LessThan(caretPosition) AndAlso _
                                   x.EndPoint.GreaterThan(caretPosition)) _
                .Select(Function(x) If(FindCodeElement(caretPosition, GetMembers(x)), x)) _
                .FirstOrDefault()
End Function

我们还需要一个基于 using/import 语句创建所有候选名称的函数

Private Sub FindAllCandidates(ByVal elem As Object, ByVal className As String)
    If TypeOf elem Is CodeFunction Then
        FindAllCandidates(CType(elem, CodeFunction).Parent, className)
    ElseIf TypeOf elem Is CodeClass Then
        mCandidates.Add(CType(elem, CodeClass).FullName & "." & className)
        FindAllCandidates(CType(elem, CodeClass).Parent, className)
    ElseIf TypeOf elem Is CodeStruct Then
        mCandidates.Add(CType(elem, CodeStruct).FullName & "." & className)
        FindAllCandidates(CType(elem, CodeStruct).Parent, className)
    ElseIf TypeOf elem Is CodeNamespace Then
        mCandidates.Add(CType(elem, CodeNamespace).FullName & "." & className)
        For Each ns As String In CType(elem, CodeNamespace).Members.OfType(Of CodeImport) _
                                                                   .Select(Function(x) x.Namespace)
            mCandidates.Add(ns & "." & className)
        Next
        FindAllCandidates(CType(elem, CodeNamespace).Parent, className)
    ElseIf TypeOf elem Is FileCodeModel Then
        For Each ns As String In CType(elem, FileCodeModel).CodeElements.OfType(Of CodeImport) _
                                                                        .Select(Function(x) x.Namespace)
            mCandidates.Add(ns & "." & className)
        Next
    End If
End Sub

然后是一个循环所有可用项目以找到候选对象之一的函数

Private Function FindClassInCodeElements(ByVal elems As CodeElements) As CodeElement
    If elems Is Nothing Then Return Nothing
    For Each elem As CodeElement In elems
        If IsClassType(elem) Then
            If mCandidates.Contains(elem.FullName) Then Return elem
        ElseIf TypeOf elem Is CodeNamespace Then
            For Each candidate As String In mCandidates
                If candidate.StartsWith(elem.FullName) Then
                    Dim found As CodeElement = FindClassInCodeElements(GetMembers(elem))
                    If found IsNot Nothing Then Return found
                    Exit For
                End If
            Next
        End If
    Next
    Return Nothing
End Function

两个小辅助函数

Private Function IsClassType(ByVal elem As CodeElement) As Boolean
    Return TypeOf elem Is CodeClass OrElse TypeOf elem Is CodeStruct OrElse TypeOf elem Is CodeInterface
End Function

Private Function GetMembers(ByVal elem As CodeElement) As CodeElements
    If TypeOf elem Is CodeClass Then
        Return CType(elem, CodeClass).Members
    ElseIf TypeOf elem Is CodeNamespace Then
        Return CType(elem, CodeNamespace).Members
    ElseIf TypeOf elem Is CodeStruct Then
        Return CType(elem, CodeStruct).Members
    ElseIf TypeOf elem Is CodeInterface Then
        Return CType(elem, CodeInterface).Members
    End If
    Return Nothing
End Function

然后我们可以编写 main 函数,您可以根据自己的使用方式对其进行更改。

Dim mCandidates As New HashSet(Of String)

Sub ExpandFullNameOfSelection()
    Dim selection As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
    ' Assume type is selected
    Dim className As String = selection.Text

    ' Find current context
    Dim currentFunction As CodeElement = FindCodeElement(selection.ActivePoint, DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElements)

    mCandidates.Clear()
    FindAllCandidates(currentFunction, className)

    Dim classType As CodeElement = DTE.Solution.Projects.Cast(Of Project) _
                                                        .Where(Function(x) x.CodeModel IsNot Nothing) _
                                                        .Select(Function(x) FindClassInCodeElements(x.CodeModel.CodeElements)) _
                                                        .FirstOrDefault(Function(x) x IsNot Nothing)
    If classType IsNot Nothing Then
        selection.Text = classType.FullName ' replace with full name
    End If
End Function

【讨论】:

  • 我正在尝试实现这一点,但出现错误:Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType , 字符串名称, Object[] 参数, String[] 参数名, Boolean[] CopyBack)
  • 错误发生在运行时,编译时很开心,所以我怀疑在哪里需要额外的排除——?
  • @user230910,该错误表明您使用了不适用于扩展方法的后期绑定。启用选项显式、严格和推断。
【解决方案3】:

JetBrains' ReSharpercan do this via the "Code Cleanup" function,以及许多其他代码更改(例如显式类型使用而不是 var 等)。

请注意,我不是附属机构,而是 R# 的忠实粉丝。

【讨论】:

    猜你喜欢
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    相关资源
    最近更新 更多