When to Avoid Lambda Expressions, or What Anonymous Methods?

by Andrew Barber 21. September 2010 15:27

A Lambda Expression (link) is a C# syntax that makes delegates so much easier to use. Rather than needing to define a separate method and pass its name, or even using an anonymous delegate, we can include the body of a quick, one-off method right in-line in our coding. The various LINQ APIs are among the major frameworks which make extensive use of Lambda Expressions, and we all know how great it is to be able to use this syntax. I'm not here to convince you to use Lambda Expressions, though.

Actually, I'm here to convince you not to use Lambdas. Sometimes, anyway. Consider this code:

itemsList.ForEach(item => DoAction(item));
...
public void DoAction(Item item) {
  //...do various things here...
}

Now, maybe here we are calling DoAction because its body is too long to fit within the lambda itself. In that case, using the ForEach() extension method to List<T> doesn't give us a lot of benefit over using the regular foreach loop, though it does save a couple lines of code, I suppose. But in this particular case, using ForEach() may have lulled us into doing something that's actually taking more code, and causing some extra thrashing on the stack than necessary;

The Argument Passed Does Not Need to Be a Lambda At All

You should simply call DoAction like this:

itemsList.ForEach(DoAction);

No Lambda at all. The key is to remember what it is you are really passing when you create a lambda expression: something of a shortcut to define a delegate instance. Yes, it also has benefits such as closure, but one should not lose site of what the method call is expecting. In this case, it's expecting an address to a method that matches the signature of Action<T>. DoAction is already such a method, so creating the lambda is just adding in a totally unnecessary method call.

LINQ Predicates Don't Need to be Lambdas, Either

One of the uses for lambdas is when the method you would otherwise define isn't going to be used anywhere else. If you don't need to create a separate method out of it for purposes of reuse, lambdas allow you to define it just once, right where it's being used. This can make code that uses lambdas much easier to follow, with less bouncing back-and-forth in the source.

But don't forget that those method arguments are again just regular delegates. Do you find yourself reusing the same predicate lambdas over and over? View those signatures and find out what they are, create a method to match and pass that in, instead of the same lambda, over and over!

Comments are closed
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent those of my partners, clients or contractors in any way.

© Copyright 2014 AndrewBarber.com