WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Refactoring in Whidbey

by Wei-Meng Lee
06/28/2004

Code refactoring is a term coined by Martin Fowler (www.refactoring.com, martinfowler.com). Even though the term may sound unfamiliar to you, many of you have actually used it. In a nutshell, code refactoring means restructuring your code so that the original intention of the code is preserved. For example, you may rename a variable so that it better reflects its usage. In this case, the entire application that uses this variable need to be updated with the new name. Another example of code refactoring is extracting a block of code and placing it into a function for more efficient code reuse. In either case, you would need to put in significant amount of effort to ensure you do not inadvertently inject errors into the modified code. In Visual Studio .NET 2005 (codenamed Whidbey), a code refactoring engine is built in. In this article, I will walk you through this new feature.

Extract Method

Very often, we write repetitive code within a function. Consider the following example:

private void Form1_Load(object sender, EventArgs e)
{
  int i, num, sum=0;
  for (i = 1; i <= num; i++) {
    sum += i;
  }
}

Here, I am summing up all the numbers from 1 to num; a very common operation. It would be better for me to package this block of code into a function. So I highlight the code (see Figure 1), right-click on it, and select Refactor -> Extract Method.


Figure 1. Extracting a block of code as a method

Supply a new name for your method (see Figure 2). You can also preview the default method signature that the refactoring engine has created for you. Click OK.


Figure 2. The Extract Method dialog

The block of statements is now encapsulated within a function:

private void Form1_Load(object sender, EventArgs e)
{
  int i, num, sum=0;
  i = Summation(num, ref sum);
}
private static int Summation(int num, ref int sum)
{
  int i;
  for (i = 1; i <= num; i++) {
    sum += i;
  }
  return i;
}

However, you still need to do some tweaking, as you obviously do not want to return the loop variant i; the variable sum should instead be returned.

The code you highlight will affect how the refactoring engine works. For example, if you include the variables declaration in the highlighting, a void function is created instead:

private static void Summation()
{
  int i, num, sum = 0;
  for (i = 1; i <= num; i++) {
    sum += i;
  }
}

While I find the method extraction feature useful, you should pay close attention to the new method signature and the return type. Often, some minor changes are needed in order to get what you want.

Consider another example:


int x, y, temp;
temp = x;
x = y;
y = temp;

If I include the variables declaration in the refactoring, a void function with no signature is generated:

private static void Swap()
{
  int x, y, temp;
  temp = x;
  x = y;
  y = temp;
}

However, if the variables declarations are not included, a method with three parameters is created:

private static void Swap(out int x, out int y, out int temp)
{
  temp = x;
  x = y;
  y = temp;
}

Here are the observations:

  • Variables that are defined outside of the highlighted block are used as an input parameter in the new method<./li>
  • If variables are declared in the block, the new method will have no signature.
  • Values that are changed within the block of highlighted code will be passed into the new method by reference.

Note that C# supports two ways to pass in a parameter by reference: ref and out. The ref keyword requires that the variable be initialized before passing into the method. The out keyword does not require a variable to be initialized prior to calling the method; its main use is to pass a value out of the method.

Encapsulate Field

Consider the following partial declaration of a MyPoint class:

public class MyPoint
{
   public float x, y;

   public void MyPoint() {}
   public void MyPoint(float _x, float _y) {
      x = _x;
      y = _y;
   }
}

Here, the x and y variables represent the x and y coordinates of a point. It would be better to expose x and y as properties, rather than public members. So highlight and right-click x and choose Refactor -> Encapsulate Field... (see Figure 3).


Figure 3. Encapsulating a member variable as a property

You can then give a name to your property (see Figure 4).


Figure 4. Naming the property

Pages: 1, 2, 3, 4

Next Pagearrow