WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Hacking Visual Studio
Pages: 1, 2, 3, 4, 5

Refactor Your Code

Visual Studio 2005 puts this fundamental tenet of Extreme Programming into action. Use it to write better code.

Refactoring is a technique for improving a section of code by modifying its internal structure, but without affecting its external behavior. Refactoring is one of the key tenets of Extreme Programming; in a rapid development methodology, the idea is to create code quickly and then refactor it as you work with it. The goal of Extreme Programming is to create better quality code by concentrating on small deliverables and continuously testing and refactoring your code. Refactoring is not just limited to Extreme Programming—it is a valuable practice regardless of the methodology you happen to subscribe to. Visual Studio 2005 introduces a new Refactor menu. This menu is available whenever you right-click and provides a number of time-saving and code-improving functions.

TIP: Refactoring is almost exclusively a C# feature. The only part of the Refactor menu that is available in VB.NET is the Rename function.

Figure 2-31 shows the menu and the various functions included there.


Figure 2-31. Refactor menu

Extract Method

The first function available in the Refactor menu is Extract Method. This can be used to select a block of code and then extract that code into a separate method. This function has a number of applications, such as removing a section of code that deserves to be in its own method for code reuse purposes. Here is some existing code:

public class Car
{
    private bool _isStarted = false;
    private bool _hasFuel = true;
  
    public Car( )
    {
        //Start the Car
         if (_hasFuel){_isStarted = true;}
    }
}

That example has a little bit of code in the constructor that checks to see if the car has fuel and then "starts" the car by setting a Boolean value. If you decide that this class needs a second constructor, instead of duplicating this tiny piece of logic, you could extract this into a separate StartCar method and then call that method from both constructors. To accomplish this with the Refactor menu: highlight the code you want to extract and then right-click and select the Extract Method function from the Refactor menu. After you select Extract Method, you see a dialog box that asks for the name of the new method (see Figure 2-32).


Figure 2-32. Extract Method dialog

Type in the new name of the method, in this case, StartCar, since it describes exactly what the method will accomplish. After you click OK, Visual Studio will modify the selected code by placing it in a new method named StartCar, then placing a call to the new method in the spot where the old code was. Here is the new code:

public Car( )
{
    //Start the Car
    StartCar( );
}
  
private void StartCar( ){if (_hasFuel){_isStarted = true;}}

Rename

The second function on the Refactor menu is the Rename function. This is one of the most time-saving functions on this menu. Suppose that you decide the name Car is a little shortsighted, since the system will need to work for Cars, Bikes, Trucks, and more. A more appropriate name would be Vehicle. Normally you would need to manually find all references to the name Car and change them; the Rename function does this for you automatically. First, right-click on the name Car and then select the Rename function from the Refactor menu; the Rename dialog will then be displayed (see Figure 2-33). The Rename dialog allows you to specify what to rename the class to; in this case, it's going from Car to Vehicle. A number of checkboxes are available; check all of them in this example. The first (Preview Reference Changes) lets you preview all of the changes to the files; the next two checkboxes (Search In Comments/Strings) tells Visual Studio to search for this name in comments as well as strings.


Figure 2-33. Rename dialog

After clicking the OK button, you will see a confirmation dialog that shows all of the changes that will be made. As you can see in Figure 2-34, the Preview Changes dialog shows where Visual Studio is going to change the name Car to Vehicle. After you click Apply, Visual Studio will make all the changes to the project.

WARNING One thing that Visual Studio does not change is the name of the StartCar method. Since Visual Studio does not look in method names when making these changes, you will have to change StartCar to StartVehicle yourself.


Figure 2-34. Preview Changes dialog

In addition to being a great time-saver, Rename removes any excuse you might make about why a class is not named appropriately.

Encapsulate Field

The Encapsulate Field function creates a public property that encapsulates your field. In the ongoing example, suppose that you need to create a public property for the _isStarted field. To do this, right-click on the field name and click the Encapsulate Field function on the Refactor menu. You are then shown the Encapsulate Field dialog, which is shown in Figure 2-35.


Figure 2-35. Encapsulate Field dialog

Visual Studio automatically sets the property name to be IsStarted and gives you the option to update references to the old field. Leave this setting as External so that code in your class is not changed to reference the public property and instead continues to use the private field. The other checkboxes are similar to the ones you saw in the Rename dialog and perform the same actions. After you click OK, you are shown a Preview Changes dialog--the same kind of dialog shown in Figure 2-34—which shows all of the changes that will result. After you accept the changes shown, the following code is added to the class:

public bool IsStarted
{
    get
    {
        return _isStarted;
    }
  
    set
    {
        _isStarted = value;
    }
}

This function comes in handy even when you are not refactoring. When creating a class for the first time, you can create the private fields and then use this function to create all of the necessary public properties.

Extract Interface

The Extract Interface function looks at your current class and creates an interface based on its public methods and properties. For example, suppose you want to create an interface for objects that can be "started"; this interface would include a Boolean property, in this case IsStarted, which, when set, has the side effect of "starting" the object (some kind of vehicle or item with an on/off switch). First, right-click on the class name and click the Extract Interface menu item; this displays the Extract Interface dialog, which is shown in Figure 2-36.


Figure 2-36. Extract Interface dialog

The default interface name is IVehicle; change it to IStart and then select the IsStarted property. After you click OK, Visual Studio creates a new file called IStart.cs with the following piece of code:

interface IStart
{
    bool IsStarted { get; set; }
}

Visual Studio will also modify the existing class to implement the new interface. The Extract Interface function is a great time-saver when you need to create an interface that is based on a current class.

Parameter Functions

The next three functions on the menu all focus on working with parameters. Since the sample class does not currently contain any methods with parameters, go ahead and add a new method with a number of different parameters. Here is a method called Collision that you can add to this class:

public void Collision(DateTime CrashDate, int Speed, int DamagePct)
{
    int costMultiplier = 1;
  
    // Do stuff
}

As you can see, this method has a local variable called costMultiplier and sets the value to 1. But suppose that costMultiplier varies from vehicle to vehicle. In this case, you'd want to pass in this multiplier as a parameter instead of creating it as a local variable. The first of the parameter refactoring functions will do just that. First, right-click on the costMultiplier variable and select the Promote Local Variable to Parameter function. This will take the local variable and add it as a parameter to the method. Here is a look at the modified code:

public void Collision(int costMultiplier, DateTime CrashDate, 
  int Speed, int DamagePct)
{
    // Do stuff
}

You may be thinking that this is not a big deal; it is basically cut and paste. But Visual Studio also goes and looks for any calls to this method and modifies them as well. If you were calling this method before with the following line of code:

Collision(DateTime.Now, 60, 10);

this method call would be changed to the following:

Collision(1, DateTime.Now, 60, 10);

Notice that Visual Studio not only adds the new parameter, but also passes in the value that the local variable was set to as well, saving time and ensuring that existing code continues to work as it did before.

Suppose you decide that you don't need the CrashDate parameter. If you won't be using it in the method, you can remove this parameter using the second of these parameter refactoring functions, called Remove Parameters. First, right-click on the method name and click Remove Parameters in the Refactor menu. You'll be shown the Remove Parameters dialog, which is shown in Figure 2-37.


Figure 2-37. Remove Parameters dialog

In the Remove Parameters dialog, you can select the CrashDate parameter, click Remove, and then click OK. You are then shown a Preview Changes dialog showing the changes that will be made to any calls to this method. After clicking Apply on that screen, those changes will be made. Any calls to this method will have this parameter removed, and the parameter will be removed from the method signature.

Further, suppose you decide that you don't want costMultiplier to be the first parameter, but rather the last parameter. This is where the last of the parameter functions comes in. First, right-click on the method, then choose the Reorder Parameters menu item on the Refactor menu. This will display the Reorder Parameters dialog, which is shown in Figure 2-38.


Figure 2-38. Reorder Parameters dialog

You can then select the costMultiplier parameter, move it down two spots, and click OK. You will again then be shown the Preview Changes dialog. where you can confirm the changes that will be made to any calls to this method. Click Apply, and the order of the parameters will be changed in the method signature and any calls to this method.

The Refactor menu is a great addition to Visual Studio and will make it much easier to refactor code. If you want to learn more about refactoring, the best resources are the book Refactoring (Addison-Wesley) and the companion web site, http://www.refactoring.com.

Want It Now?

Tired of waiting for Visual Studio 2005 or stuck using Visual Studio .NET 2003 for some reason? A number of commercial tools are available that add similar functionality into Visual Studio .NET 2003:

ReSharper

From Jet Brains:

http://www.jetbrains.com/resharper

C# Refactory

From XtremeSimplicity:

http://www.xtreme-simplicity.NET/CSharpRefactory.htm


View catalog information for Visual Studio Hacks

Return to ONDotnet.com.