Coding and Dismantling Stuff

Don't thank me, it's what I do.

About the author

Russell is a .Net developer based in Lancashire in the UK.  His day job is as a C# developer for the UK's largest online white-goods retailer, DRL Limited.

His weekend job entails alternately demolishing and constructing various bits of his home, much to the distress of his fiance Kelly, 3-year-old daughter Amelie, and menagerie of pets.

TextBox

  1. Fix dodgy keywords Google is scraping from my blog
  2. Complete migration of NHaml from Google Code to GitHub
  3. ReTelnet Mock Telnet Server à la Jetty
  4. Learn to use Git
  5. Complete beta release FHEMDotNet
  6. Publish FHEMDotNet on Google Code
  7. Learn NancyFX library
  8. Pull RussPAll/NHaml into NHaml/NHaml
  9. Open Source Blackberry Twitter app
  10. Other stuff

Four Of The Best Linq Extension Methods

If you've read any of my previous blog posts, you might have the feeling that I absolutely love Lambdas in .Net, they're just plain awesome. Get a good handle on Lambdas, and you can chuck out a good wedge of your crummy old nested "foreach" statements. When the language feature first came on the scene, Lamdas seemed (to my eyes at least) to be confined to the world of Linq extension methods. Since then of course there's been a plethora of tools that have jumped on, such as Fluent NHibernate and Moq, but there's still plenty of life in the ol' Linq extension method yet! Here are my top four linq extensions, the lifesavers that I keep coming back to.

.Where(x => x...) - Using Linq to Filter a Collection

The granddaddy of Linq statements, if you don't know the Where method yet, you've (almost) never lived. The Where method simply takes a collection, applies a predicate to each of its members, and returns a new list containing only the matching items. The following simple example would assign a new collection containing the numbers 0, 3, 6 and 9 to the variable multiplesOfThree.

IList<int> numberList = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var multiplesOfThree = numberList.Where(num => num % 3 == 0).ToList();

I mentioned the word "Predicate" a moment ago, some of you may be wondering what a predicate is exactly. A predicate is a method, delegate or statement that returns a boolean, indicating whether some condition has passed or failed. In the code above, the predicate is the bit that says "num % 3 == 0".  The num variable is available thanks to the lambda bit before your predicate (the "num =>" bit).  So altogether, the "num => num % 3 == 0" bit is your lambda predicate. On its own, this code snippet doesn't do anything, but inside the Where method this code is executed against each item in your collection in order to construct the result.

.Any(x => x...) - Using Linq to Find a Match

Now we've seen Linq filtering lists, and I assume this is no big whoop to a lot of you reading, let's look at some of the less common Linq methods. What if we want to say "does anything in my list match a condition"? Commonly I see this done as follows:

IList<Order> orderList = OrderRepository.GetOrders();
bool areAnyOrdersPending = orderList.Where(x => x.IsPending).Count() > 0;

This works, but there's a problem with this code - if your collection contains 10,000 orders, and they're all pending, your lambda check is executed 10,000 times. If all we want to know is whether any item matches our condition, we could've stopped at the first match. This is where the Any method comes in - as soon as any item in your collection is a match, it'll tell you straight away and stop evaluating the remaining items.

IList<Order> orderList = OrderRepository.GetOrders();
bool areAnyOrdersPending = orderList.Any(x => x.IsPending);

I'm not a huge fan of the method name "Any", it doesn't seem intuitive in code (perhaps ContainsAny would have been better). but it works, and it's a darn site more concise than the Where(...).Count() option.

.Select(x => x...) - Linq to Transform a Collection

So far the Linq extension methods we've looked at have been kinda "read-only" - we're just looking at a collection and either getting a filtered copy of it, or seeing if it contains what's in it. These next few methods are more about transforming and generating different views of your data.

The first time I came across the Select method, it was a good year or two after I'd become familiar with the Where method, I was pretty gutted it had taken me so long, Select is pretty magical. You have a collection of data in one format, and you need to transform it into a collection in a different format, this is the method for you. Take a look at the following example:

IList<Order> orderList = OrderRepository.GetOrders();
IList<OrderContactDetails> contactDetails = orderList.Select(
  x => new OrderCustomer(x.OrderNumber, x.Customer.EmailAddress));

That second line of code is taking your orderList collection, and for each item it's generating a new object of type OrderContactDetails with the order number and customer email address. When it's done, you get a shiny new collection populated with a transformed copy of your original data.

This type of code transform is very common when working with MVC or MVP, you'll frequently find yourself generating light-weight objects from your business entities to render them onto your views, this method is perfect for this job.

.SelectMany(x => x...) - Linq to Flatten a Collection of Collections

This one's nice and simple, it takes a collection of collections and flattens them out into a single collection. Let's say our Order object contains a list of addresses, and each address contains a list of telephone numbers, we want to get a simple list of all the telephone numbers on the order:

Order order = OrderRepository.Orders("ABC");
IList<string> allTelephoneNos = order.Addresses.SelectMany(addr => addr.TelephoneNos);

The job this particular extension method does is a real pain to do traditionally - I can picture in my head at least 4 lines of code involving an icky nested loop to do the same thing!

A Final Note -Linq Extension Methods vs Linq Query Syntax

In a word, usually don't (okay, in two words). From a personal perspective, as soon as I see chains of Linq statements, particularly if there're multiple uses of lamdas, you're now into linq query syntax territory. It's not a hard fast rule, there are some interesting points made over on StackOverflow on the subect of Linq Extension Methods vs Linq Syntax, but as a general rule I prefer query syntax as soon as things get complicated.

I may come up with a teeny little blog post about some linq query syntax best practice, who knows!


Categories: Architecture
Permalink | Comments (0)

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading