Monday, December 31, 2007

Mug

Hello again, X-mas celebrants! I have just one last verse in my carol to make all of your Visual Studio 2008 experiences bright. Don't let your hearts be saddened because my song is drawing to a close. After today, a new year filled with its own code blessings will be upon us.

My last offering is a simple one—a stocking stuffer, really. It's one last refactoring targeted at Visual Basic developers.

And so, it is with a heavy heart that I begin the last verse of the "Twelve Days of Refactor! X-mas..."

"On the twelfth day of X-mas my true love (DevExpress) gave to me..."

Extract XML Literal to Resource

In my opinion, the most compelling new feature of Visual Basic 9 is XML Literals. We've already seen how Refactor! Pro can be used to manipulate XML Literals to great effect, saving literally hundreds of keystrokes. However, sometimes we don't want to dynamically build XML. Sometimes we simply want to consume a chunk of raw XML.

Module TwelveDaysOfXmas
  Sub Main()
    Dim lBook = <book isbn="12252007">
                 <title>Refactoring: The True Meaning of X-mas</title>
                 <price>$0.00</price>
                 <author>
                   <first-name>Dustin</first-name>
                   <last-name>Campbell</last-name>
                 </author>
               </book>
  End Sub
End Module

If we're not adding embedded expressions to the above XML literal, it really belongs in a resource file. However, moving that XML to a resource is a terrible inconvenience. Thankfully, Refactor! Pro provides the Extract XML Literal to Resource refactoring. When applied to the code above, Extract XML Literal to Resource produces the following:

Module TwelveDaysOfXmas
  Sub Main()
    Dim lBook = XElement.Parse(My.Resources.XMLFile)
  End Sub
End Module

When compared to the acrobatics we've already seen Refactor! Pro perform on XML Literals, this refactoring might seem like a very small thing. It may be simple, but it's incredibly helpful when you need it. The first time that you attempt to move an XML Literal to a resource for translation purposes or any other reason, you'll be thankful that you have Extract XML Literal to Resource to do the job for you.

Check Out This Screencast to See Everything that Extract XML Literal to Resource Handles for You!

And so ends my song. We've taken a merry sleigh ride through many of the new language features available in Visual Studio 2008, and we've seen how Refactor! Pro can help you leverage those features today. It's been my distinct pleasure to be your guide on this journey.

Before I take my leave, I have one small piece of advice. If you've been waiting impatiently for the other tool to support for Visual Studio 2008, remember that Refactor! Pro has been there since the very first beta. No matter what that tool vendor may try to tell you, Visual Studio 2008 was not a surprise. Everyone had more than a year to prepare. The only ones taken by surprise were those who weren't paying attention.

And with that, I wish you a continued happy holiday season and hope Refactor! Pro can make your new year bright!

Happy New Year!

posted on Monday, December 31, 2007 1:57:09 PM (Eastern Standard Time, UTC-05:00)  #    Comments [5]

kick it on DotNetKicks.com
 Sunday, December 30, 2007

Mug

Greetings friends! I bring tidings of comfort and joy! That is, you can rest comfortably and joyously, knowing that you don't have to wait for refactorings that leverage the new language features of Visual Studio 2008. These refactorings are available today.

I'm very excited about today's verse. As promised yesterday, I'm back to share some more refactoring possibilities for Visual Basic XML Literals. By the end of the verse, you should have a sense of how powerful these refactorings truly are. If you're a Visual Basic developer, you definitely won't want to miss this!

"On the eleventh day of X-mas my true love (DevExpress) gave to me..."

More Refactoring in XML Literals

Yesterday, we saw how our bread-and-butter refactorings can be used on the inner text of XML tags to create new embedded expressions. This is extremely helpful when trying to make the contents of an XML literal more dynamic. Today, we'll take things a step further to see how we can use Refactor! Pro to manipulate the XML tags themselves.

Module TwelveDaysOfXmas
  Sub Main()
    Dim aPrice As Decimal = 0
    Dim lBook = <book isbn="12252007">
                 <title>Refactoring: The True Meaning of X-mas</title>
                 <price><%= aPrice.ToString("C") %></price>
                 <author>
                   <first-name>Dustin</first-name>
                   <last-name>Campbell</last-name>
                 </author>
               </book>
  End Sub
End Module

Consider the code above. Since Refactor! Pro works on XML tags, we can select the entire <price> tag and apply Extract Method to get the following:

Module TwelveDaysOfXmas
  Private Function GetPrice(ByVal aPrice As Decimal) As XElement
    Return <price><%= aPrice.ToString("C") %></price>
  End Function

  Sub Main()
    Dim aPrice As Decimal = 0
    Dim lBook = <book isbn="12252007">
                 <title>Refactoring: The True Meaning of X-mas</title>
                 <%= GetPrice(aPrice) %>
                 <author>
                   <first-name>Dustin</first-name>
                   <last-name>Campbell</last-name>
                 </author>
               </book>
  End Sub
End Module

A potential complication is the use of aPrice in the embedded expression. Fortunately, Extract Method intelligently analyzes this and declares it as a parameter of the new method.

View Screencast to See Extract Method in Action!

Refactor! Pro's ability to manipulate XML tags makes it easy to dynamically build XML. In fact it can save minutes of menial coding labor.

Take another look at the first code example above. Go ahead. I'll wait.

Now, imagine how much effort it would take to transform that code into this:

Module TwelveDaysOfXmas
  Private Function GetTitle(ByVal aTitle As String) As XElement
    Return <title><%= aTitle %></title>
  End Function

  Private Function GetPrice(ByVal aPrice As Decimal) As XElement
    Return <price><%= aPrice.ToString("C") %></price>
  End Function

  Private Function GetAuthor(ByVal aFirstName As String, _
                             ByVal aLastName As String) As XElement
    Return <author>
             <first-name><%= aFirstName %></last-name>
             <last-name><%= aLastName %></last-name>
           </author>
  End Function

  Private Function GetBook(ByVal aPrice As Decimal, _
                           ByVal aIsbn As String, _
                           ByVal aTitle As String, _
                           ByVal aFirstName As String, _
                           ByVal aLastName As String) As XElement
    Return <book isbn=<%= aIsbn %>>
             <%= GetTitle(aTitle) %>
             <%= GetPrice(aPrice) %>
             <%= GetAuthor(aFirstName, aLastName) %>
           </book>
  End Function

  Sub Main()
    Dim lBook = GetBook(0D, _
                  "12252007", _
                  "Refactoring: The True Meaning of X-mas", _
                  "Dustin", _
                  "Campbell")
  End Sub
End Module

That's pretty insane, isn't it? Well, with Refactor! Pro, this is a snap. In fact, most of the effort is spent typing the names of new variables and methods. The refactorings themselves take only seconds to apply.

Don't Believe Me? Check Out This Screencast!

One point I've saved until now is that Refactor! Pro is the very first tool to offer refactorings for Visual Basic XML Literals. That's just one more compelling reason that Refactor! Pro should be a part of your Visual Studio 2008 installation this holiday season.

Happy Holidays!

posted on Sunday, December 30, 2007 6:58:57 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]

kick it on DotNetKicks.com
 Saturday, December 29, 2007

Mug

I'm afraid that I have an apology to make. I feel that I've given my Visual Basic friends a raw deal because the verses of my carol thus far have been primarily about C#. Oh sure, the verses usually end with a paragraph or two mentioning how a particular refactoring works in VB, but I haven't devoted a whole verse exclusively to a Visual Basic 9 feature. Until now. Today's verse is dedicated specifically to the coolest new feature of Visual Basic 9: XML Literals.

So, sit back and relax. It's time for a little Visual Basic X-mas cheer!

"On the tenth day of X-mas my true love (DevExpress) gave to me..."

Refactoring in XML Literals

A couple of months ago, I wrote about how we were adding first-class refactoring support for Visual Basic XML Literals. If you're unfamiliar with XML Literals, they allow developers to embed XML directly into their code like so:

Module TwelveDaysOfXmas
  Sub Main()
    Dim lBook = <book isbn="12252007">
                 <title>Refactoring: The True Meaning of X-mas</title>
                 <price><%= 0D.ToString("C") %></price>
                 <author>
                   <first-name>Dustin</first-name>
                   <last-name>Campbell</last-name>
                 </author>
               </book>
  End Sub
End Module

It's the VB Compiler's job to transform the above XML Literal into instances of XElements, XAttributes and XNames from the System.Xml.Linq namespace.

Module TwelveDaysOfXmas
  Sub Main()
    Dim lBook = New XElement("book", _
                    New XAttribute("isbn", "12252007"), _
                    New XElement("title", "Refactoring: The True Meaning of X-mas"), _
                    New XElement("price", 0D.ToString("C")), _
                    New XElement("author", _
                        New XElement("first-name", "Dustin"), _
                        New XElement("last-name", "Campbell")))
  End Sub
End Module

The real power of XML Literals is the ability to embed expressions directly into the XML. In the first code example above, the <price> tag contains an embedded expression.

<price><%= 0D.ToString("C") %></price>

Embedded expressions open the door to dynamic XML generation. Very, very cool.

The only real problem that I have with XML Literals is that embedded expressions are such a pain to write. Not only does the expression itself have to be written, but the delimiters contain no less than five symbols. Granted, VB's IntelliSense fills in the last two after I've typed the first three, but that's still three characters to type with the shift key held down. That's pretty painful. It would be great if a refactoring tool existed that handled this work for us. Oh wait. I work on a refactoring tool that does that very thing. That's right, Refactor! Pro works on XML Literals!

Check out the preview hint for Introduce Local when the contents of the <title> tag are selected:

Introduce Local on Xml Literal Preview Hint

And here's the code after Introduce Local is applied:

Introduce Local on Xml Literal

Visual Basic developers everywhere can rejoice. You no longer have to type <%= again because the bread-and-butter refactorings work in XML Literals!

View Screencast of XML Literal Refactoring in Action!

Tomorrow: more refactorings for XML Literals. You won't want to miss it!

posted on Saturday, December 29, 2007 1:40:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Friday, December 28, 2007

Cookies

Welcome back for more X-mas refactoring fun! There are just four more verses in my carol, but I'll make them count. Refactor! Pro can bless your Visual Studio 2008 installation in many more ways, so I'll have to pick the very best.

"On the ninth day of X-mas my true love (DevExpress) gave to me..."

Expand Lambda Expression

In my sixth verse, I described a feature of Refactor! Pro that enables developers to leverage the dreaded lambda expressions. That refactoring (Compress to Lambda Expression) provides a way to transform an anonymous method into a lambda expression. Today we're looking at lambda expressions from the opposite perspective—transforming a lambda expression into an anonymous method. Expand Lambda Expression is the refactoring that performs this conversion. Given the lambda expression in the code below...

using System;

namespace TwelveDaysOfXmas
{
  class Program
  {
    static void Main()
    {
      var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

      var numberText = Array.ConvertAll<int, string>(numbers, n => n.ToString("x8"));

      foreach (var text in numberText)
        Console.WriteLine(text);
    }
  }
}

Expand Lambda Expression will produce this:

using System;

namespace TwelveDaysOfXmas
{
  class Program
  {
    static void Main()
    {
      var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

      var numberText = Array.ConvertAll<int, string>(numbers, delegate(int n)
                                                              {
                                                                return n.ToString("x8");
                                                              });

      foreach (var text in numberText)
        Console.WriteLine(text);
    }
  }
}

I'm sure that some of you are scratching your heads. "Why in the world would I want to do that? Aren't lambda expressions better?" Well, yes. However, transforming a lambda expression into an anonymous method makes other refactorings available. For example, after expanding our lambda expression, we might want to use Name Anonymous Method to make the anonymous method a member of the current type. That way, we're promoting code reuse. Check out the preview hint for Name Anonymous Method below.

Name Anonymous Method Preview Hint

Once Name Anonymous Method is applied, we can give the new method a good name and we're done!

using System;

namespace TwelveDaysOfXmas
{
  class Program
  {
    private static string GetHexText(int n)
    {
      return n.ToString("x8");
    }
    static void Main()
    {
      var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

      var numberText = Array.ConvertAll<int, string>(numbers, GetHexText);

      foreach (var text in numberText)
        Console.WriteLine(text);
    }
  }
}

View Screencast of Expand Lambda Expression and Name Anonymous Method in Action!

I must say, it gladdens my heart to know that there is a tool available right now that allows me to refactor the latest and greatest language features of Visual Studio 2008. In fact, we've raised the bar by releasing a major update to Refactor! Pro. That's right, Refactor! Pro 3.0 is now available and ships with 150 refactorings for C#, Visual Basic, C++, ASP .NET, XAML, and even JavaScript. The future is looking very bright indeed!

posted on Friday, December 28, 2007 3:53:10 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Thursday, December 27, 2007

Coffee and Mug

Today, I saw the following tweet on Twitter:

dredding: @jfollas taking coffee away from a developer is like taking away a dominatrix's whip. You just don't do it.

This made me smile—not because of how creepy my friend Dave Redding is (very creepy), but because of how true the sentiment is. At least, it's true for me. Coffee is an addiction that I've fully embraced. It's difficult for me to start a day without that bold flavor. Some developers might choose to get their buzz in another way (and a smaller percentage choose to have none at all), but I've picked coffee as my caffeine-delivery system of choice.

I've really become quite the coffee snob. For me, only the very best coffee will do. I buy my coffee whole bean from Grounds for Thought in Bowling Green, OH. Of all the roasts they produce, Kenya "Gazelle" AA and Papua New Guinea "Mile High" Estate AA+ are definitely my favorites. The Kenya has a nice bite that wakes me up while the New Guinea is smooth all the way down.

But what is it about caffeine that causes many developers crave it so? I mean, aside from the fact that it helps wake us up in the mornings. It certainly doesn't make me a nicer person to be around. In fact, too much makes me downright grouchy. However, the right amount seems to put my brain in a zone that sees problems more clearly. It's almost as if the caffeine gives my think meat the extra zip that it needs to solve problems. Perhaps caffeine unlocks areas of our minds that allow us to be better developers, if only for a moment.

Then again, maybe that's just the coffee talkin'.

posted on Thursday, December 27, 2007 7:48:14 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]

kick it on DotNetKicks.com

Bells

JustinKohnen: @dcampbell: um... Christmas is over dude ;)

That was posted on Twitter today when I announced that I was working on this very blog entry. Well, I've got news for Mr. Justin "X-mas-Hater" Kohnen. X-mas isn't over until the fat... uhhh... lady sings. (Hmmm... that worked out much better in my head.)

While X-mas day has come and gone, the holiday season continues. I have enough verses left in my song to ensure that our merry-making runs all the way 'til the new year.

"On the eighth day of X-mas my true love (DevExpress) gave to me..."

Bread-and-Butter Refactorings in Query Expressions

Since LINQ is such a big part of what C# 3.0 and Visual Basic 9 are all about, I thought that showing two more examples of refactorings that can be used in query expressions would be useful. The refactorings we'll look at do not target query expressions specifically. Instead, these are pre-existing, bread-and-butter refactorings that have been updated to support query expressions properly.

What's a "bread-and-butter refactoring" you ask? It's one of those refactorings that you can't live without—a part of your everyday arsenal. It's important to know that these crucial refactorings work with the latest and greatest language features.

OK, let's get started!

public static int SumOfEvenSquares(int count)
{
  return (from number in Enumerable.Range(1, count)
          where (number % 2) == 0
          select number * number).Sum();
}

There are a number of refactorings that we could apply to the LINQ code above. First, let's use Introduce Local to generate a new local variable assigned to the query expression. This is easy enough to do. Just select the query expression, press the Refactor key (CTRL+` by default), choose Introduce Local, and press ENTER. Below is a screenshot of the preview hint for Introduce Local.

Introduce Local Preview Hint

The More You Know
If you are unfamiliar with Refactor! Pro's preview hints, they are sort of like windows into the future. A preview hint shows what a refactoring will do before you apply it. This feature provides the advantage you need to refactor your code with confidence.

After naming the new local variable, our refactored code looks like so:

public static int SumOfEvenSquares(int count)
{
  IEnumerable<int> evenSquares = from number in Enumerable.Range(1, count)
                                 where (number % 2) == 0
                                 select number * number;
  return evenSquares.Sum();
}

View Screencast of Introduce Local in Action!

I would be remiss if I didn't mention that there is another way to use Introduce Local. In addition to pressing the Refactor key, it is also possible to apply the refactoring using cut-and-paste. 99% of the time, when cutting an expression to the clipboard and pasting it within the same method on an empty line above the cut location, the user's intention is to create a local variable assigned to that expression. Refactor! Pro takes advantage of this knowledge to anticipate the user's intent and automatically apply Introduce Local.

View Screencast of Introduce Local Using Cut-And-Paste!

One of the red flags that some have raised against query expressions is their potential to cause code duplication. For example, the expressions in the where and select clauses from the sample code above really should be extracted to new methods. That way, we promote code reuse. If not, we are doomed to write the same tiny, bite-sized expressions over and over. Fortunately, Refactor! Pro's Extract Method refactoring works perfectly on these expressions. With Extract Method, we can easily turn the code above into:

private static IEnumerable<int> GetNaturals(int count)
{
  return Enumerable.Range(1, count);
}
private static bool IsEven(int number)
{
  return (number % 2) == 0;
}
private static int Square(int number)
{
  return number * number;
}
public static int SumOfEvenSquares(int count)
{
  IEnumerable<int> evenSquares = from number in GetNaturals(count)
                                 where IsEven(number)
                                 select Square(number);
  return evenSquares.Sum();
}

Believe it or not, using Refactor! Pro, I'm able to produce that code in just 42 keystrokes—including 23 keystrokes for the method names and 12 for navigation and selection. That means that only seven keystrokes are actually needed to apply three Extract Method refactorings!

Curious? View the Screencast of Extract Method in Action!

Finally, I must mention that Extract Method can be used with cut-and-paste just like Introduce Local. That's right, you can cut code to the clipboard and paste it on an empty line outside of a method. Extract Method will take over. Again, Refactor! Pro is working hard to anticipate your intentions.

View the Screencast of Extract Method Using Cut-And-Paste!

And thus ends the eighth verse of my song. Today we've looked at how two bread-and-butter refactorings, Introduce Local and Extract Method, can be used within LINQ expressions. The coolest thing is that all of the screencasts were recorded using Visual Studio 2008. They aren't mock ups of future features. These refactorings work with query expressions this very minute!

My Visual Basic friends might be a little worried because I didn't show these refactorings working in Visual Basic. Well, rest assured, the refactorings work fine. In fact, they work using the same keystrokes!

Now, that's what I call an X-mas present.

posted on Thursday, December 27, 2007 6:38:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Wednesday, December 26, 2007

Presents

Season's greetings! We're halfway through my X-mas carol describing how Refactor! Pro can be used to leverage the new features of Visual Studio 2008. Today, I'm sharing a little more Refactor! Pro love by demonstrating a refactoring that literally can save minutes of menial coding. That's right, minutes. Interested? OK, just let me clear my voice...

"On the seventh day of X-mas my true love (DevExpress) gave to me..."

Create Backing Store

A couple of days ago, I showed how Refactor! Pro can transform properties into C# 3.0 Auto-Implemented Properties. However, sometimes the opposite is needed. We need a way to convert from an auto-implemented property to a standard property and field. Consider the following code:

using System;
using System.Drawing;

namespace TwelveDaysOfXmas
{
  class Present
  {
    public Color Color1 { get; set; }
    public Color Color2 { get; set; }
  }
}

Suppose that we want to add logic to both the Color1 and Color2 properties to ensure that they can't be set to the same value. Now, imagine how much effort that would take. An awful lot of keystrokes are needed to get to the code below.

using System;
using System.Drawing;

namespace TwelveDaysOfXmas
{
  class Present
  {
    private Color m_Color1;
    public Color Color1
    {
      get { return m_Color1; }
      set
      {
        if (m_Color2 == value)
          return;
        m_Color1 = value;
      }
    }
    private Color m_Color2;
    public Color Color2
    {
      get { return m_Color2; }
      set
      {
        if (m_Color1 == value)
          return;
        m_Color2 = value;
      }
    }
  }
}

Fortunately, Refactor! Pro provides a refactoring, called Create Backing Store, which converts an auto-implemented property into a standard property with a field backing store. In other words, it transforms this...

public Color Color1 { get; set; }

...into this.

private Color m_Color1;
public Color Color1
{
  get
  {
    return m_Color1;
  }
  set
  {
    m_Color1 = value;
  }
}

That's pretty close to what we want. With the help of two other refactorings, Introduce Setter Guard Clause and Collapse Accessor, we can continue to manipulate the property to get the code below.

private Color m_Color1;
public Color Color1
{
  get { return m_Color1; }
  set
  {
    if (m_Color1 == value)
      return;
    m_Color1 = value;
  }
}

Now we just have to make a minor edit to the guard clause and we're done.

View Screencast of These Refactorings in Action!

And that concludes my verse for today. Remember that the features I'm showing you are available for download this very second. So, if you're tired of waiting for <whisper>the other tool</whisper> to get its act together, Refactor! Pro can have you running laps through Visual Studio 2008 in no time.

posted on Wednesday, December 26, 2007 3:52:42 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Tuesday, December 25, 2007

Presents

Merry X-mas friends! It is indeed X-mas day, and I have returned with a special gift for you. Today, I'm doing my part to bring peace on earth and goodwill toward developers by showing one way that Refactor! Pro can simplify the dreaded lambda expressions. I'll achieve this by showing three refactorings which can be used together to transform some very C-ish code into modern C# 3.0 code.

And now, it's time to continue my anthem.

There's a hush. All is quiet. Then, in the silence, a still, small voice is heard. It grows louder and louder until...

"On the sixth day of X-mas my true love (DevExpress) gave to me..."

Compress to Lambda Expression

I'm not exactly sure why, but every time that I mention "lambda expressions" to developers, their faces show confusion and terror. My guess is that this reaction is caused by one of three things:

  1. A fear of Greek letters (i.e. "lambda")
  2. A fear of all things pointy (i.e. the => operator that lambda expressions bristle with.)
  3. A fear of all things functional (i.e. passing functions around like candy.)

It's for these reasons that I'll demonstrate a couple of other refactorings first. We'll work our way up to lambda expressions. Let's start with something more familiar.

using System;
using System.Collections.Generic;

namespace TwelveDaysOfXmas
{
  class CompressToLambdaExpression
  {
    public static int SumList(List<int> list)
    {
      int sum = 0;
      for(int i = 0; i < list.Count; i++)
        sum += list[i];
      return sum;
    }
  }
}

The code above is an example of the sort of imperative code that we write all of the time. What do I mean by "imperative?" Well, it's like writing a recipe for the computer—describing, in excruciating detail, the steps to solve a problem. There's nothing terribly wrong with that. After all, it's how our computer processors work. They execute a list of instructions—one at a time. However, there is another way that this code can be written.

On the other side of the coin from imperative code is declarative code. Declarative code describes what should be done instead of specifically how it should be done. Writing code declaratively has many potential benefits over the imperative style.

  1. It can be easier to read.
  2. It can be easier for the compiler/runtime to optimize.
  3. It can promote code reuse.

We can write the above code a bit more declaratively by using a foreach loop.

using System;
using System.Collections.Generic;

namespace TwelveDaysOfXmas
{
  class CompressToLambdaExpression
  {
    public static int SumList(List<int> list)
    {
      int sum = 0;
      foreach (int number in list)
        sum += number;
      return sum;
    }
  }
}

That's better! To save keystrokes, Refactor! Pro provides a For to ForEach refactoring that easily performs this conversion. Here's how the preview hint for this refactoring looks:

For to ForEach Preview Hint

Another declarative possibility is to call the List<T>.ForEach method instead using of a foreach loop. In that case, we would pass an anonymous delegate to the method as the body of the loop like so:

using System;
using System.Collections.Generic;

namespace TwelveDaysOfXmas
{
  class CompressToLambdaExpression
  {
    public static int SumList(List<int> list)
    {
      int sum = 0;
      list.ForEach(delegate(int number)
      {
        sum += number;
      });
      return sum;
    }
  }
}}

In a declarative fashion, the above code states, "loop through the entire list, and execute this function (delegate) for each item in the list." A powerful feature of the anonymous delegate is that it references a variable (sum) outside of the delegate body, producing a closure. (For more information on closures, check out this article.)

Of course, Refactor! Pro provides a refactoring that renders this transformation trivial: Introduce ForEach Action. The screenshot below shows the preview hint for this refactoring.

Introduce ForEach Action Preview Hint

Now, some of you might be saying, "Whoa! That anonymous delegate sure is an ugly little spud1." You're right, it is. Enter the lambda expression.

I don't want to present an entire history of lambda expressions here, but you should understand that they pre-date computers entirely. So, if you've been wondering where these crazy new things came from, know that they really aren't crazy "new" things. Lambda expressions have been around since the 1930s.

A C# lambda expression is really just an anonymous delegate on steroids. It retains all of the functionality of an anonymous delegate but adds conciseness, better type inference and even pseudo-meta-programming via expression trees.

Using a lambda expression is straight-forward, if a little funky:

using System;
using System.Collections.Generic;

namespace TwelveDaysOfXmas
{
  class CompressToLambdaExpression
  {
    public static int SumList(List<int> list)
    {
      int sum = 0;
      list.ForEach(number => sum += number);
      return sum;
    }
  }
}

If this is the first time that you've seen a lambda expression in the wild, compare it with the anonymous delegate that we used before. The parameters are declared to the left of the => operator, and the body is declared to the right. The compiler works out the types of the parameters so there's no need to specify them.

Of course, my X-mas present for you today is another refactoring: Compress to Lambda Expression. This refactoring (available now) converts anonymous delegates into lambda expressions, saving dozens of keystrokes and head scratches. Again, here is the preview hint to show what this refactoring does:

Compress to Lambda Expression Preview Hint

View Screencast of These Refactorings in Action!

As always, I'm demonstrating features of Refactor! Pro that can be used to leverage the new features in Visual Studio 2008 right now. In fact, all of the refactorings above have been shipping for several months. In other words, these aren't in some super-secret beta. They have been released.

As another refactoring goodie has been successfully unwrapped, it's time to take my leave of you. Until tomorrow, have a warm and happy X-mas!

1Ray Stanz, Ghostbusters.

posted on Tuesday, December 25, 2007 12:31:26 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]

kick it on DotNetKicks.com
 Monday, December 24, 2007

Nutcracker

'Twas the night before X-mas, when all through the house,
Not a creature was stirring, not even a mouse;
The stockings were hung by the chimney with care,
In hopes that DevExpress soon would be there;
The children were nestled all snug in their beds,
While visions of
Refactor! Pro danced in their heads.

Ho, ho, ho! I'm back to stuff your stockings with another feature of Refactor! Pro that lets you leverage Visual Studio 2008 on this fine X-mas Eve.

But wait! Who's that knocking at your front door? Why it's a group of carolers, here to sing a noël for us. Shhh! They're about to begin.

"On the fifth day of X-mas my true love (DevExpress) gave to me..."

Convert to Auto-Implemented Property

One of the tastiest syntactic sugar cookies that has been added to C# 3.0 is Auto-Implemented Properties. This feature allows C# developers to define properties far more concisely than before. Here's how we used to define properties in C# 2.0:

using System;
using System.Drawing;

namespace TwelveDaysOfXmas
{
  class Present
  {
    private Color m_Color;
    private bool m_HasBow;

    public Present(Color color, bool hasBow)
    {
      m_Color = color;
      m_HasBow = hasBow;
    }

    public Color Color
    {
      get { return m_Color; }
    }
    public bool HasBow
    {
      get { return m_HasBow; }
      set { m_HasBow = value; }
    }
  }
}

Whew! That's a lot of effort! Thanks to auto-implemented properties, we can now define our properties like so:

using System;
using System.Drawing;

namespace TwelveDaysOfXmas
{
  class Present
  {
    public Present(Color color, bool hasBow)
    {
      Color = color;
      HasBow = hasBow;
    }

    public Color Color { get; private set; }
    public bool HasBow { get; set; }
  }
}

Convert to Auto-Implemented Property is a refactoring that can be used to change the first example into the second example. Check out the preview hint below to see everything that this refactoring will do for you.

Convert to Auto-Implemented Property Preview Hint

  1. It removes the field that serves as the backing store for the property.
  2. It converts all field references into references to the property.
  3. It replaces the property with an auto-implemented version. I should point out that the refactoring intelligently generates an auto-implemented property with a private setter because the property is read-only (write-only properties are handled similarly).
  4. There i