Delegates => Lambdas, Pt. 3: Lambda Expressions

This is a series I created on my company's internal intranet for a few young developers.  However, I thought it might be useful to anyone, so I wanted to make it public.


In my last post, I explained how to use anonymous methods, or inline delegates, to remove a bunch of unnecessary code from your class.  This post is going to explain how lambda expressions are really just a syntatic helper to aid in the removal of more 'extra' code and to make anonymous methods a little more readable.

And that's really what lambda expressions are - cleaner ways to write anonymous methods/inline delegates.

Let's look at our example from last time.  To handle two different filtering scenarios, we had this:

   1:  IList<TeamDTO> allTeams = new List<TeamDTO>
   2:                                            {
   3:                                                new TeamDTO("Flyers", "East"),
   4:                                                new TeamDTO("Blackhawks", "West"),
   5:                                                new TeamDTO("Blue Jackets", "West"),
   6:                                                new TeamDTO("Capitals", "East")
   7:                                            };
   8:   
   9:  IList<TeamDTO> easternTeams = SelectTeamsByFilter(allTeams, delegate(TeamDTO team) { return team.Conference == "East"; });
  10:   
  11:  IList<TeamDTO> teamsThatStartWithLetterB = SelectTeamsByFilter(allTeams, delegate(TeamDTO team) { return team.TeamName.StartsWith("B"); });

This isn't bad, but you still have to use the delegate keyword and declare a function, complete with parentheses and curly braces inline. That can get hard to match up pretty quickly. So here are these same lines using lambda expressions:

   1:  IList<TeamDTO> allTeams = new List<TeamDTO>
   2:                                            {
   3:                                                new TeamDTO("Flyers", "East"),
   4:                                                new TeamDTO("Blackhawks", "West"),
   5:                                                new TeamDTO("Blue Jackets", "West"),
   6:                                                new TeamDTO("Capitals", "East")
   7:                                            };
   8:   
   9:  IList<TeamDTO> easternTeams = SelectTeamsByFilter(allTeams, team => team.Conference == "East");
  10:  IList<TeamDTO> teamsThatStartWithLetterB = SelectTeamsByFilter(allTeams, team => team.TeamName.StartsWith("B"));

As I said earlier, this is really just a cleaner way to write the delegate. The left side of the lambda expression declares the inputs. You will often see these as x. That's just a convention. I chose team because I think it's more descriptive. The right side of the lambda expression holds the statement block, or function body. Pretty simple - lambda expressions are delegates. Nothing to be afraid of.

A few notes about lambda expressions before this post is over.

When a lambda expression's body contains only one line of code, you don't need a return - the result of that line of code is assumed to be the return value. So above, the line evaluates to a boolean, so that is considered the return value. That said - you CAN write lambda expressions containing multiple lines of code, but you then have to include the return keyword and wrap your expression body in curly braces. Here's a quick example:

   1:  return SelectTeamsByFilter(allTeams, team => {
   2:                                                           int count = team.TeamName.Length;
   3:                                                           return count == 10;
   4:                                                       });

Not super realistic, it filters by teams whose name is ten characters long.

Also - lambda expressions can take zero parameters. In that case, you use an empty set of parentheses on the left side like this:

   1:  () => SomeMethod()

And they can also take multiple inputs. For example, if you wanted to compare two teams:

   1:  (team1, team2) => team1.TeamName == team2.TeamName

So there you go. Lambda expressions are nothing more than clean ways to write delegates. And delegates are a really powerful and useful feature to allow you to separate a method from its implementation.

There's going to be one more post in this series. It's a bit of a tangent rather than a continuation, but I wanted to introduce a few classes that .NET provides to help facilitate the use of delegates in your code. So look for that in the next couple of days.

Print | posted @ Thursday, August 13, 2009 1:18 PM

Comments on this entry:

No comments posted yet.

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 6 and 3 and type the answer here: