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..."
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:
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.
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.
We can write the above code a bit more declaratively by using a foreach loop.
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:
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:
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.
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:
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:
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.
Page rendered at Wednesday, February 08, 2012 9:24:28 AM (Pacific Standard Time, UTC-08:00)
If feel a bit behind and need to catch up on WPF, this is the book.
Great book on F# containing from Beginner to Advanced. It even has chapters on more arcane features of the language, such as Computation Expressions and Quotations.
Because this book provides source code in Standard ML, it's a fantastic resource for learning F#. One bit of warning: this book does not teach classic data structures. While structures such as binomial heaps and red-black trees are presented, it is assumed that the reader already knows and understands them.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.