7 Refactoring Methods in Visual Studio 2010

7 Refactoring Methods in Visual Studio 2010

Professional Visual Studio 2010 bookThe following sections describe each of the Visual Studio 2010 refactoring options and provide examples of how to use built-in support for both C# and CodeRush Xpress for VB.

Extract Method

One of the best ways to start refactoring a long method is to break it up into several smaller methods. The Extract Method refactoring action is invoked by selecting the region of code you want moved out of the original method and selecting Extract Method from the context menu. In C#, this will prompt you to enter a new method name, as shown in Figure 8-11. If there are variables within the block of code to be extracted that were used earlier in the original method, they automatically appear as variables in the method signature. Once the name has been confirmed, the new method is created immediately after the original method. A call to the new method replaces the extracted code block.

Visual Studio 2010 Extract refactoring method

Figure 8-11

For example, in the following code snippet, if you wanted to extract the conditional logic into a separate method, you would select the code, shown in bold, and choose Extract Method from the right-click context menu:

C#

private void button1_Click(object sender, EventArgs e)

{

    string connectionString = Properties.Settings.Default.ConnectionString;

    if (connectionString == null)

    {

        connectionString = "DefaultConnectionString";

    }

    MessageBox.Show(connectionString);

    /* … Much longer method … */

}

This would automatically generate the following code in its place:

C#

Private void button1_Click(object sender, EventArgs e)

{

 

    string connectionString = Properties.Settings.Default.ConnectionString;

    connectionString = ValidateConnectionString(output);

    MessageBox.Show(connectionString);

    /* … Much longer method … */

}

        

private static string ValidateConnectionString(string connectionString)

{

    if (connectionString == null)

    {

        connectionString = "DefaultConnectionString";

    }

    return connectionString;

}

CodeRush Xpress handles this refactoring action slightly differently for VB developers. After you select the code you want to replace, CodeRush Xpress prompts you to select a place in your code where you want to insert the new method. This can help developers organize their methods in groups, either alphabetically or according to functionality.

Figure 8-12 illustrates the aid that appears which enables you to position where the method should be inserted using the cursor keys.

Figure 8-12

After selecting the insert location, CodeRush Xpress inserts the new method, giving it an arbitrary name. In doing so it highlights the method name, enabling you to rename the method either at the insert location or where the method is called (see Figure 8-13).

Figure 8-13

Using the Extract Method refactoring on the following code:

VB

Private Sub Button1_Click(ByVal sender As System.Object,

                          ByVal e As System.EventArgs) Handles Button1.Click

 

    Dim connectionString As String = My.MySettings.Default.ConnectionString

    If connectionString Is Nothing Then

        connectionString = "DefaultConnectionString"

    End If

    MessageBox.Show(connectionString)

    ’Much longer method

End Sub

And renaming the method to give it an appropriate name will result in the following code:

VB

Private Sub Button1_Click(ByVal sender As System.Object,

                          ByVal e As System.EventArgs) Handles Button1.Click

    Dim connectionString As String = My.MySettings.Default.ConnectionString

    ValidateConnectionString(connectionString)

    MessageBox.Show(connectionString)

    ’Much longer method

End Sub

        

Private Shared Sub ValidateConnectionString(ByRef connectionString As String)

    If connectionString Is Nothing Then

        connectionString = "DefaultConnectionString"

    End If

End Sub

Encapsulate Field

Another common task when refactoring is to encapsulate an existing class variable with a property. This is what the Encapsulate Field refactoring action does. To invoke this action, select the variable you want to encapsulate and then choose the appropriate refactoring action from the context menu. This gives you the opportunity to name the property and elect where to search for references to the variable, as shown in Figure 8-14.

Visual Studio 2010 Encapsulate Field refactoring

Figure 8-14

The next step after specifying the new property name is to determine which references to the class variable should be replaced with a reference to the new property. Figure 8-15 shows the preview window that is returned after the reference search has been completed. In the top pane is a tree indicating which files and methods have references to the variable. The checkbox beside each row indicates whether a replacement will be made. Selecting a row in the top pane brings that line of code into focus in the lower pane. Once each of the references has been validated, the encapsulation can proceed. The class variable is updated to be private, and the appropriate references are also updated.

Figure 8-15

The Encapsulate Field refactoring action using CodeRush Xpress works in a similar way, except that it automatically assigns the name of the property based on the name of the class variable. The interface for updating references is also different, as shown in Figure 8-16. Instead of a modal dialog, CodeRush Xpress presents a visual aid that can be used to navigate through the references (or you can navigate between references using the Tab key). Where a replacement is required, click the check mark or press Enter. Unlike the C# dialog box, in which the checkboxes can be checked and unchecked as many times as needed, once you accept a replacement there is no way to undo this action.

 

Figure 8-16

Extract Interface

As a project goes from prototype or early-stage development to a full implementation or growth phase, it’s often necessary to extract the core methods for a class into an interface to enable other implementations or to define a boundary between disjointed systems. In the past you could do this by copying the entire method to a new file and removing the method contents so you were just left with the interface stub. The Extract Interface refactoring action enables you to extract an interface based on any number of methods within a class. When this refactoring action is invoked on a class, the dialog in Figure 8-17 is displayed, which enables you to select which methods are included in the interface. Once selected, those methods are added to the new interface. The new interface is also added to the original class.

Visual Studio 2010 Extract Interface refactoring

Figure 8-17

In the following example, the first method needs to be extracted into an interface:

C#

public class ConcreteClass

{

    public void ShouldBeInInterface()

    { /* … */ }

        

    public void AnotherNormalMethod(int ParameterA, int ParameterB)

    { /* … */ }

        

    public void NormalMethod()

    { /* … */ }

}

Selecting Extract Interface from the right-click context menu and selecting only the ShouldBeInInterface method to be extracted from the Extract Interface dialog introduces a new interface (in a new file) and updates the original class as follows:

C#

interface IBestPractice

{

    void ShouldBeInInterface();

}

        

public class ConcreteClass: Chapter08Sample.IBestPractice

{

    public void ShouldBeInInterface()

    { /* … */ }

        

    public void NormalMethod(int ParameterA, int ParameterB)

    { /* … */ }

        

    public void AnotherNormalMethod()

    { /* … */ }

}

Extracting an interface is also available within CodeRush Xpress, however it doesn’t allow you to choose which methods you want to include in the interface. Unlike the C# interface extraction, which places the interface in a separate file (which is recommended), CodeRush Xpress simply extracts all public class methods into an interface in the same code file. For example, using CodeRush Xpress’s Extract Interface refactoring action on the following class:

VB

Public Class ConcreteClass

    Public Sub ShouldBeInInterface()

        ’…

    End Sub

        

    Public Sub NormalMethod(ByVal ParameterA As Integer,

                            ByVal ParameterB As Integer)

        ’…

    End Sub

        

    Public Sub AnotherNormalMethod()

        ’…

    End Sub

End Class

Will result in the following code:

VB

Public Interface IConcreteClass

    Sub ShouldBeInInterface()

    Sub NormalMethod(ByVal ParameterA As Integer, ByVal ParameterB As Integer)

    Sub AnotherNormalMethod()

End Interface

Public Class ConcreteClass

    Implements IConcreteClass

    Public Sub ShouldBeInInterface() Implements IConcreteClass.ShouldBeInInterface

        ’…

    End Sub

        

    Public Sub NormalMethod(ByVal ParameterA As Integer,

                            ByVal ParameterB As Integer) _

                            Implements IConcreteClass.NormalMethod

        ’…

    End Sub

        

    Public Sub AnotherNormalMethod() Implements IConcreteClass.AnotherNormalMethod

        ’…

    End Sub

End Class

Rename

Visual Studio 2010 provides rename support in both C# and VB. The Rename dialog for C# is shown in Figure 8-22; it is similar in VB although it doesn’t have the options to search in comments or strings.

Unlike the C# rename support, which displays the preview window so you can confirm your changes, the rename capability in VB simply renames all references to that variable.

Visual Studio 2010 Rename refactoring

Figure 8-22

Promote Variable to Parameter

One of the most common refactoring techniques is to adapt an existing method to accept an additional parameter. Promoting a method variable to a parameter makes the method more generic. It also promotes code reuse. Intuitively, this operation would introduce compile errors wherever the method was referenced. However, the catch is that the variable you are promoting to a parameter must have an initial constant value. This value is added as a parameter value to all the method references to prevent any changes to functionality. Starting with the following snippet, if the method variable output is promoted, you end up with the second snippet: 

VB

Private Sub MethodA()

    MethodB()

End Sub

        

Private Sub MethodB()

    Dim output As String = "Test String"

    MessageBox.Show(output)

End Sub

C#

public void MethodA()

{

    MethodB();

}

public void MethodB()

{

    string output = "Test String";

    MessageBox.Show( output);

}

After the variable is promoted, you can see that the initial value is now being passed through as a parameter wherever this method is referenced:

VB

Private Sub MethodA()

    MethodB("Test String")

End Sub

        

Private Sub MethodB(ByVal output As String)

    MessageBox.Show(output)

End Sub

C#

public void MethodA()

{

    MethodB("Test String");

}

public void MethodB(string output)

{

    MessageBox.Show( output);

}

Generate Method Stub

As you write code, you may realize that you need to call a method that you haven’t written yet. For example, the following snippet illustrates a new method that you need to generate at some later stage:

VB

Private Sub MethodA()

    Dim InputA As String

    Dim InputB As Double

    Dim OutputC As Integer = NewMethodIJustThoughtOf(InputA, InputB)

End Sub

C#

public void MethodA()

{

    string InputA;

    double InputB;

    int OutputC = NewMethodIJustThoughtOf(InputA, InputB);

}

Of course, the preceding code generates a build error because this method has not been defined. Using the Generate Method Stub refactoring action (available as a smart tag in the code itself), you can generate a method stub. As you can see from the following sample, the method stub is complete with input parameters and output type:

VB

Private Function NewMethodIJustThoughtOf(ByVal InputA As String,

                                         ByVal InputB As Double) As Integer

    Throw New NotImplementedException

End Function

C#

private int NewMethodIJustThoughtOf(string InputA, double InputB)

{

    throw new Exception("The method or operation is not implemented.");

}

EDITOR’S NOTE: Additional refactoring methods are covered in the complete section on this topic in the book Professional Visual Studio 2010.

This article is excerpted from chapter 8 "Code Snippets and Refactoring " of the book Professional Visual Studio 2010 by Nick Randolph, David Gardner, Chris Anderson, Michael Minutillo (ISBN: 978-0-470-54865-3, Wrox, 2010, Copyright Wiley Publishing Inc.)

Tags:

Comments

4 Responses to “7 Refactoring Methods in Visual Studio 2010”

  1. Anonymous says:

     >> Unlike the C# dialog box, in which the checkboxes can be checked and unchecked as many times as needed, once you accept a replacement there is no way to undo this action.
    Duly noted — undo here is not as granular as it could be. However you can press Undo (Ctrl+Z) after the confirmation phase is complete. This will undo the entire Encapsulate Field refactoring.
    - Mark Miller
    Dev Express

  2. Anonymous says:

    It is useful for me

  3. Anonymous says:

    It is very good for programmer.
     

  4. Anonymous says:

    I think ,i should learn this ebook for programming

Leave a Reply

What is 13 + 4 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)