Refactoring is the process of changing code so that
the code becomes more manageable and extensible without affecting the existing
functionality. Apart from easy maintainability refactoring also improves the
overall structure of the code. Refactoring involves lot of manual work using
search and replace features of code editors. This manual process apart from
being tiresome is also prone to errors. Thanks to Visual Studio 2005 which
eliminates most of the manual work by providing support for automatic
refactoring. This article will explain the various refactoring techniques
supported by Visual Studio 2005.
Refactoring Techniques in VS
2005
VS 2005 supports the following refactoring
techniques
- Extract Method
- Rename
- Encapsulate Field
- Extract Interface
- Promote Local Variable To Parameter
- Remove Parameters
- Reorder Parameters
Extract Method
Using Extract Method refactoring technique we
can extract required lines from an existing method and create a new method from
it. This is done by selecting the required lines from existing method and
choosing Refactor->Extract method from the context menu. A new method will be
created with selected code and the selected code in existing method will be
replaced by a call to the new method. For example consider the following
code
publicclassRefactoringSample
{
publicRefactoringSample()
{
int
length;
int
breadth;
Console.WriteLine("Enter
Length");
length =
Convert.ToInt32(
Console.ReadLine());
Console.WriteLine("Enter
Breadth");
breadth =
Convert.ToInt32(Console.ReadLine());
}
}
Other methods in the class may also need the same
information in which case the code will become redundant. The ideal way would be
to put the code in constructor in a separate method so that it becomes reusable.
All we have to do is select the code within the constructor and choose
Refactor->Extract from the context menu. A popup dialog box asking us to
enter the name for the new method will appear. Once we give the name for the
new method and click OK the following is the recfactored code will be
generated
publicRefactoringSample()
{
NewMethod();
}
privatestaticvoid
NewMethod()
{
int
length;
int
breadth;
Console.WriteLine("Enter
Length");
length =
Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter
Breadth");
breadth =
Convert.ToInt32(Console.ReadLine());
}
The new method generated would be defined as private
and static since we have not referred to any instance variable. If we had
referred to any instance variable the new method would be defined as private.
Also the code we hade selected does not require any inputs and does not give any
output so the new method is generated without arguments and return
value.
Rename
Rename refactoring technique provides an easy
way to change the name of variables, controls, methods etc throughout the
project. This relives developers from the pain of changing the names wherever
the identifier is being used. For example let us consider the following
code
privatestaticvoid
TestMethod(int
i)
{
Console.WriteLine("Half
of " + i +
" Is
" + i / 2);
Console.WriteLine("Square
of " + i +
" Is
" + i * i);
Console.WriteLine("Cube
of " + i +
" Is
" + i * i * i);
}
And for some reason we want to change the parameter
name from i to inputNumber. All we have to do is select i in the method
signature and choose Refactor->Rename. This would popup a dialog box which
asks us the new name. Once we enter the new name and click ok the code would be
refactored as shown below
privatestaticvoid
TestMethod(int
inputNum)
{
Console.WriteLine("Half
of " + inputNum +
" Is
" + inputNum / 2);
Console.WriteLine("Square
of " + inputNum +
" Is
" + inputNum * inputNum);
Console.WriteLine("Cube
of " + inputNum +
" Is
" + inputNum * inputNum *
inputNum);
}
Rename refactoring can also be used to change
names in comments as well as strings. Also when we change the name of control in
WinForm property window or WebForm property window Rename refactoring
will be automatically initiated and the control name will be renamed throughout
the code.
Encapsulate Field
When a field is defined as public it is directly
accessible to the outside world which is against the laws of encapsulation.
Encapsulate Field refactoring technique converts public fields into
properties and also updates the code with reference to the new property. For
example consider the following code
publicclassRefactoringSample
{
publicint
length;
publicint
breadth;
}
For converting the public field length to property all
we have to do is place the cursor in the length field and select
Refactor->Encapsulate Field from the context menu. This will open a dialog
box asking for the new property name. Once we give the name and click ok the
following refactored code will be generated
publicclassRefactoringSample
{
privateint
length;
publicint
Length
{
get
{
return
length;
}
set
{
length =
value;
}
}
publicint
breadth;
}
If you notice the above code we can see that the
length field is a made private and a public property named Length with get and
set accessors is generated. If the field is read-only the property will be
generated with only get accessor. Also the refactoring engine will update the
code with references to the newly created property.
Extract Interface
When multiple classes or structs have a set of members
common it will be useful to have these members within an interface and make the
classes or structs derive from this interface. This will make the code more
readable and manageable. Extract Interface refactoring technique allows
us to create a new interface with members from existing class or struct. For
example consider the following class
publicclassCar
{
publicvoid
Start()
{
//Code here
}
publicvoid
Move()
{
//Code here
}
}
The class Car has two methods Start and Move which can
be used for other type of vehicles such as Truck, Bus etc. It would be better if
the common code is moved to an interface. For this all we have to do is select
the methods we want to move to an interface and choose Refactor-> Extract
Interface from the context menu. This would popup a dialog box asking for the
interface name and members to be included in the interface. Once we give the
name a new file defining the interface will be created with the code
below
using
System;
interfaceIVehicle
{
void
Move();
void
Start();
}
Also the code in original class will be changed as
follows
publicclassCar
:
IVehicle
{
publicvoid
Start()
{
//Code here
}
publicvoid
Move()
{
//Code here
}
}
Promote Local Variable To
Parameter
Some times when we are defining a method we may that
it be better to move some of the local variables in the method to parameters of
the method so that the method becomes more generic. Promote Local Variable To
Parameter refactoring technique allows us to move local variable in a method
as a parameter to the method. For example consider the following
code
publicclassRefactoringSample
{
publicRefactoringSample()
{
ReadFileContent();
}
publicvoid
ReadFileContent()
{
string
FileName = @"C:\My
Folder\Sample.Txt";
//Code here
}
}
Here it would be more useful if the file name is
passed as an argument to ReadFileContent method. For this all we have to do is
select the vaible we would like to promote as parameter and choose
Refactoring->Promote Local Variable To Parameter from the context menu. This
will change the code as follows
publicclassRefactoringSample
{
publicRefactoringSample()
{
ReadFileContent(@"C:\My
Folder\Sample.Txt");
}
publicvoid
ReadFileContent(string
FileName)
{
//Code here
}
}
In the above code you can notice that the Promote
Local Variable To Parameter refactoring technique has not only promoted the
local variable as parameter but has also updated the all references to the
method with the new parameter.
Remove Parameter
As the name suggests the Remove Parameter
refactoring technique allows us to remove parameters from a methods signature.
For example consider the following code
publicclassRefactoringSample
{
publicRefactoringSample()
{
SampleMethod("A","B");
}
publicvoid
SampleMethod(string
arg1,string
arg2)
{
//Code here
}
}
If we want to remove the second argument from the
SampleMethod method all we have to do is place cursor within the method and
select Refactor->Remove paramter from the context menu. This will popup a
dialog box asking us to select the parameters we would like to remove. Once we
select arg1 and click ok the following code will be generated
publicclassRefactoringSample
{
publicRefactoringSample()
{
SampleMethod("A");
}
publicvoid
SampleMethod(string
arg1)
{
//Code here
}
}
In the above code you can notice that the Remove
Parameter refactoring technique has not only removed the parameter but has
also updated the all references to the method.
Reorder Parameters
As the name suggests the Reorder Parameters
refactoring technique allows us to change the order of parameters in a method.
For example consider the following code
publicclassRefactoringSample
{
publicRefactoringSample()
{
ReadFromFile(5,
"MyFile");
}
publicvoid
ReadFromFile(string
FileName)
{
//Code here
}
publicvoid
ReadFromFile(int
NoOfchars,string
FileName)
{
//Code here
}
publicvoid
ReadFromFile(string
FileName,int
NoOfChars,int
StartPos)
{
//Code here
}
}
In the above code the first and third overloaded
ReadFromFile methods place the FileName as the frist argument whereas the second
method places the FileName argument last. Though this is valid it will confuse
the user. In order to change the position of parameters all we have to do to is
place cursor within the method and select Refactor->Reorder Parameters from
the context menu. This will popup a dialog box which has provision for changing
the order or parameters. Once we reorder the parameters and click ok the
following code will be generated
publicclassRefactoringSample
{
publicRefactoringSample()
{
ReadFromFile("MyFile",
5);
}
publicvoid
ReadFromFile(string
FileName)
{
//Code here
}
publicvoid
ReadFromFile(string
FileName,
int
NoOfchars)
{
//Code here
}
publicvoid
ReadFromFile(string
FileName,int
NoOfChars,int
StartPos)
{
//Code here
}
}
In the above code you can notice that the Reorder
Parameters refactoring technique has not only changed the order of
parameters but has also updated the all references.
This article explained the various refactoring
techniques supported in Visual Studio 2005. Do ping me at sriram@dotnetforce.com
for further discussion on this or incase you have any
doubts.