简体   繁体   中英

Is there any function or tool (free) to auto complete any .Net type name to fully qualified one?

I'm using VB.NET with Visual Studio 2010. Is there any function or tool to auto complete any.Net type name to fully qualified one?

I mean a tool/function that actually changing the source code from short hand to fully qualified name like following:

From String to System.String

From Process.Start to this System.Diagnostics.Process.Start

UPDATE:

Thanks for ReSharper suggestion. But I'm not prepared to buy it or award bounty for a commercial product suggestion. Sorry about that . I should make my question clear about that requirement. I already tried ReSharper before asking this question.

Resharper is capable of doing this.

Although Resharper is not free, it is absolutely worth buying. Once started using Resharper, you will not be able to proceed without it.

Showing the step by step below, because it is not quite trivial how to do this:

  1. Download and install Resharper.
  2. Open VS and go to menu Rehsarper => Options => Languages => C# => Namespace Import . Select Use fully qualified names . By default Insert using directives when necessary is selected.

    在此处输入图像描述

    From now on, whenever you use Alt+Enter to resolve namespace, Resharper will resolve fully qualified one.

  3. Go to Rehsarper => Options => Tools => Code cleanup . Hit Add button to add new Cleanup profile. Give a name to the new profile, eg Namespaces Reformat . Check Optimizing using directives checkbox.在此处输入图像描述

  4. Right click on the project and select Cleanup Code... , or use shortcut Ctrl+E, Ctrl+C . Select previously created profile and hit Run button.

    在此处输入图像描述


Test

Original code:

using System;

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

Result code:

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

Here is a macro that works fine for C# code.

When I tested it on a VB.Net project it didn't work for types in assembly references. Seems like the project code model for VB.Net excludes external types.

I include the code here anyway. Maybe someone else knows how to do it for VB


First we need a function that finds the current context

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

We also need a function that create all candidate names based on using/import statements

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

And then a function that loops all available items to find one of the candidates

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

Two small helper functions

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

And then we can write the main function which you can alter depending on how you want to use it.

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

JetBrains' ReSharper can do this via the "Code Cleanup" function , along with many other code changes (such as explicit type usage instead of var etc.).

Note that I'm not affiliated, but a big fan of R#.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM