Delegates => Lambdas, Pt. 4: .NET Helpers (The Final Episode)

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.


Ok - this is the last part of my series about delegates and lambdas.  Finally.  But I wanted to mention a few helpers that .NET provides to make it easier to use delegates and lambdas in your code.

If you remember back to the first post of the series, I mentioned that to declare a delegate to be used as a parameter or anything else, you had to do this:

   1:  delegate bool Filter(TeamDTO team);

Well - .NET makes it slightly less tedious with the use of three framework classes, namely Action<T>, Predicate<T> and Func<T>. Let's look at an example of each.

Action<T>:

This class encapsulates a delegate that takes one parameter and does not return a value. Meaning, it is a contract that specifies one input parameter, the type of which is specified as a generic, and a void return type. This is useful for a variety of scenarios, but let me show you just one.

If you've noticed, when you create a List<T>, one of the methods on that list that is built-in for .NET is ForEach(Action action). Using that, you can build for-each loops using delegates/lambdas. See below:

   1:  private readonly List<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:  Action<TeamDTO> printTeam = x => Response.Write(x.TeamName);
  10:  allTeams.ForEach(printTeam);

Or, you can just inline it all with a lambda expression like this:

   1:  allTeams.ForEach(x => Response.Write(x.TeamName));

By the way, Action<T> also comes in a few additional flavors, those being Action<T1, T2>, Action<T1, T2, T3> and Action<T1, T2, T3, T4>.  As you can probably guess, this just allows you to use them to define up to 4 input parameter types - the return value in all situations is still void.

Predicate<T>:

This is another .NET class representing another standard delegate situation.  This one takes one parameter and returns a boolean value.  This is actually PERFECT for our filter situation.  Instead of having to create a delegate like the one at the top of this post, we can use this in it's place, since it does the same thing (takes in one argument, it's generic, but we can specify we want it to be of type TeamDTO and returns a boolean value).  So let's see it in action:

   1:  private static IList<TeamDTO> SelectTeamsByFilter(IEnumerable<TeamDTO> teams, Predicate<TeamDTO> filter)
   2:  {
   3:       var filteredTeams = new List<TeamDTO>();
   4:       foreach (TeamDTO team in teams)
   5:       {
   6:            if (filter(team))
   7:            {
   8:                 filteredTeams.Add(team);
   9:            }
  10:       }
  11:   
  12:       return filteredTeams;
  13:  }

Compare this piece of code to the one in the first post of the series and you see that I just replaced the delegate object I created with the Predicate - why re-invent what .NET already has?

Func<T>:

This one actually comes in a bunch of different flavors and is arguably the most powerful.  And actually, if you look at the MSDN documentation, Func<T> is actually not even the correct form of the delegate - but this is how it's used in conversation.  The actual name is Func<TResult>.  And hopefully by now you're catching on and can guess what that means.  Func<TResult> allows you to specify a delegate with no input parameters and a return value of TResult.  Like Action<T>, Func<TResult> has variations that allow you to specify up to 4 input parameters, in addition to the return type.  So you have Func<TResult>, Func<T, TResult>, Func<T1, T2, TResult>, Func<T1, T2, T3, TResult> and Func<T1, T2, T3, T4, TResult>.   Keep in mind if you use these that the last value will be the return value in any situation.

As a really simple example, imagine I wanted a function that printed all of the team names in a list.  Here it is:

   1:  Func<TeamDTO, string> printTeamName = x => x.TeamName;
   2:  foreach (TeamDTO team in allTeams)
   3:  {
   4:       printTeamName(team);
   5:  }

The first line defines a Func<T, TResult> that accepts a TeamDTO object and returns a string.  Then the lambda shows that x is the input parameter and on the other side of the => is the return statement x.TeamName.  The other part is just a for-loop which invokes the delegate.

So that's it for my series on delegates and lambda expressions.  But it won't be the last time you hear about them.  A lot of the examples in these posts were scholastic in nature, but they probably left you thinking that aside from being neat, where was the benefit?  Where all of these helpers, and delegates in general, become really powerful is when you combine them with other features of .NET.  So expect to see more of these in future posts.  But hopefully these gave you a few ideas about where you could benefit from the use of delegates, or at least help your understanding about what exactly is going on when you type code into your IDE of choice.

Any questions/comments/feedback? Feel free to comment any of the posts.

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.

Delegates => Lambdas, Pt. 2: Anonymous Methods == Inline Delegates

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 introduced delegates and briefly showed you how to use them, along with explaining a few of the benefits.  At the same time, there were some drawbacks as well that I probably didn't mention, but may have hinted at.

I suggest you look at that post again to refresh your memory about how delegates are declared and used.  The first thing you might notice that is a little less than ideal about the last example is that you still need to declare a function for each of your filters - IsEasternConferenceTeam, TeamNameStartsWithB, etc.  At that point, why don't you just call them directly in your code instead of passing them into another function?

This is where anonymous methods come in.  Anonymous methods allow you to declare methods inline using the delegate keyword.  This cuts down on unnecessary private functions bulking up your code.

Let's take a look at an example.  As a quick refresher, in the last post, we had this for filtering:

   1:  private static bool IsEasternConferenceTeam(TeamDTO team)
   2:  {
   3:       return team.Conference == "East";
   4:  }
   5:   
   6:  private static bool TeamNameStartsWithB(TeamDTO team)
   7:  {
   8:       return team.TeamName.StartsWith("B");
   9:  }
  10:   
  11:  IList<TeamDTO> allTeams = new List<TeamDTO>
  12:                                            {
  13:                                                new TeamDTO("Flyers", "East"),
  14:                                                new TeamDTO("Blackhawks", "West"),
  15:                                                new TeamDTO("Blue Jackets", "West"),
  16:                                                new TeamDTO("Capitals", "East")
  17:                                            };
  18:   
  19:  IList<TeamDTO> easternTeams = SelectTeamsByFilter(allTeams, IsEasternConferenceTeam); // will return a list wtih Flyers and Capitals
  20:   
  21:  IList<TeamDTO> teamsThatStartWithLetterB = SelectTeamsByFilter(allTeams, TeamNameStartsWithB); // will return a list with Blackhawks and Blue Jackets

Those two functions at the top are really just different filters. Seems a little bulky. So with anonymous methods we can do this instead:

   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"); });

Now - we can get rid of those functions.  And we can write whatever types of filters we want inline in code wherever we need to filter things.

Again - notice that as long as long as the contract is fulfilled for this delegate (TeamDTO input, boolean output), there will be no complaints from the compiler.  And just like I mentioned before, these functions can actually do as much as work as you'd like them to - they don't need to be just one line.  Of course, when you get into writing them inline like this, big functions that do a lot of heavy lifting quickly become hard to format.  But for quick one-liners, I think this is awesome.  And imagine, like I mentioned in my last post, how easy it is now for consumers of this code to write new filters?

The next step is from anonymous methods to lambdas.

Delegates => Lambdas, Pt. 1: What's A Delegate?

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.


I'm going to take the next few blog posts to explain lambda expressions (and delegates) - something we use every day as LINQ users.  But it's important to know what they are and why they're useful, beyond just knowing that the way to get a DB record matching a certain Id is by writing x => x.Id == 42.  Hopefully these posts will start to get some thoughts going about other ways that lambdas could be used.

To understand lambdas, it's important to understand what came before them  - namely, delegates.  So this first post is going to explain what delegates are.  But first a quick history lesson - when I say "what came before them", I'm talking about the history of .NET only.  Delegates and lambdas have been around for a long time.  They've been in the computer realm since LISP, Python has them and Ruby actually relies heavily on them.  And function pointers have been around forever as well.  So .NET is late to the party.

There are a few ways to think about delegates.  A delegate is a pointer to a function, meaning you can create an instance of an object that is really a function and you can invoke that function through the instance.  Another way to think about them, and the way that seems to resonate with me the most, is that a delegate is similar to an interface, but pertaining to functions - it defines a template or a contract.  You create a delegate and it says "any function that conforms to my standard will take in these inputs and produce this type of return value".  Let's look at an example.

 

   1:  delegate bool Filter(TeamDTO team);

There's your delegate definition.  It looks like any other function definition, except for the delegate keyword.  What this delegate is doing is defining a template for any function that has a boolean return value and takes a TeamDTO object as a parameter.  Any function that does those two things will fulfill this template.  The name Filter is useful to explain what type of functions this should be applied to, but it could be named anything because it's an type definition.

So what's so useful about this?  Well - you can imagine that at different times, you might want to filter a list based on different criteria.  In my example, I'm going with hockey teams (as usual).  Maybe at one point in the application, I want to get only the teams in the Eastern Conference.  Another time, I might want to only get the teams whose name starts with the letter B.  The ideas are endless.  Without delegates, this is achievable - you just have to create a bunch of different functions called FilterByWhatever and implement the same thing over and over again.  Furthermore, what if I release this code to the public as a class library and a user wants to do a search that I haven't written a function for?  With the delegate in place, we can write a function like this:

 
   1:  public static IList<TeamDTO> SelectTeamsByFilter(IEnumerable<TeamDTO> teams, Filter filter)
   2:  {
   3:       var filteredTeams = new List<TeamDTO>();
   4:       foreach(TeamDTO team in teams)
   5:       {
   6:            if(filter(team))
   7:            {
   8:                 filteredTeams.Add(team);
   9:            }
  10:       }
  11:   
  12:       return filteredTeams;
  13:  }

Notice that the 2nd parameter of that function is an instance of our delegate.  With that in place, we can pass in a function that satisfies the delegate definition and invoke it within the SelectTeamsByFilter function.  You can see that I've done just that in the IF statement.

So for the two examples above, what if I wanted to be able to filter a list of teams by their conference?  Or only teams that start with the letter B?  You can just create functions that satisfy the contract of the delegate (accept a TeamDTO as a parameter and return a boolean).  And then pass them into the SelectTeamsByFilter function like so:

   1:  private static bool IsEasternConferenceTeam(TeamDTO team)
   2:  {
   3:       return team.Conference == "East";
   4:  }
   5:   
   6:  private static bool TeamNameStartsWithB(TeamDTO team)
   7:  {
   8:       return team.TeamName.StartsWith("B");
   9:  }
  10:   
  11:  IList<TeamDTO> allTeams = new List<TeamDTO>
  12:                                            {
  13:                                                new TeamDTO("Flyers", "East"),
  14:                                                new TeamDTO("Blackhawks", "West"),
  15:                                                new TeamDTO("Blue Jackets", "West"),
  16:                                                new TeamDTO("Capitals", "East")
  17:                                            };
  18:   
  19:  IList<TeamDTO> easternTeams = SelectTeamsByFilter(allTeams, IsEasternConferenceTeam); // will return a list wtih Flyers and Capitals
  20:   
  21:  IList<TeamDTO> teamsThatStartWithLetterB = SelectTeamsByFilter(allTeams, TeamNameStartsWithB); // will return a list with Blackhawks and Blue Jackets

Yes.  I just passed functions into another function to be run.  Pretty sweet.  And to go back to my other example where someone who is using my compiled library wants to do a search that I haven't written code for - as long as they call this function with a method that conforms to the contract of the delegate (once more - takes a TeamDTO and returns a boolean value), it'll run.  And these don't have to be as simple as the examples above.  They can do as much work inside the functions as you'd like - they just have to stick to the input and output contract of the delegate.

So hopefully you are beginning to see how delegates are useful features and maybe some nice ways to use them in your code to cut down on the amount of repeated code or make your code easier to extend or whatever else.  In the next part of the series, I'll get into some ways to improve upon this code to make it a little more understandable and a little less cumbersome and move closer to how lambdas were born in the .NET framework.

In the meantime, feel free to leave any questions/comments/thoughts.