LINQ. Four little letters that have totally changed the way I program, heck its even changed the way I think about programming! Language Integrated Natural Query, four beautiful words!
So what brought this up today? Well for the past couple of weeks I’ve been working on an long term customer’s code, code that I have been involved with off and on since 2000. Truth be told, I’ve written the major part of it, and architecturally designed 94% of it. Anyways, I’ working on getting a feature working that I told the client “oh that will be no problem with WCF” back in 2006. My entries on WCF recently have been related to this project as well. Anyways, I originally wrote a major section of the code in VS 2005, but about 3 months ago upgraded it to VS 2008 (and the .Net Framework 3.5).
So as I was working on a bug (its the packet size WCF problem I’ve already bitched about here) when one of my solutions required me to filter out some items for serialization. I had removed some “sheets”, and since those sheets had been removed I could remove any dependent “subset” objects from the collection. But in this case the comparison would need to be a Hound of The Baskervilles type of search
“But Holmes, the Dog did nothing last night!”
”Exactly Watson!”
I need to look thru each subset and see if there a sheet that needs it. Since I have been looking at old migrated vs2005 code for the past couple of weeks, I started to do it the normal way in the time of the Old Ones…
foreach ( var subset in SubsetTemplates ) {
foreach ( var sheet in Sheets ) {
if ( sheet.SubsetVersionUid == subset.SubsetVersion ) {
//found it, so get out
break;
}
//if we got here let's remove it
SubsetTemplates.Remove( subset );
}
}
When I realized, wait, I can use LINQ, after adding a quick
at the start of the page, I modified it to
foreach ( var subset in SubsetTemplates ) {
var sheets = (from sheet in Sheets
where sheet.SubsetVersionUid == subset.SubsetVersion
select sheet).ToList();
if ( sheets.Count == 0 ) {
SubsetTemplates.Remove( subset );
}
}
Which is easier to read what I am intending to do, and if that was a far as LINQ had gone, I’d be a happy camper, but NOO, the guru’s at Microsoft went one step further and decided, let’s make Lambda expressions work with LINQ, and now WOW my code can shine! Here is the final code I used, and is it so much better then the original option. Wait, Wait, keep reading after the next example
foreach ( var subset in SubsetTemplates ) {
if ( Sheets.Count(
s => s.SubsetVersionUid == subset.SubsetVersion) == 0
) {
SubsetTemplates.Remove( subset );
}
}
So when I started this entry I thought the above code was my final code, but as I was working on this I realized that I could do the whole operation in one LINQ / Lambda expression
SubsetTemplates.RemoveAll(
t => Sheets.Count( s => s.SubsetVersionUid == t.SubsetVersion ) == 0
);
OK, that is cool, and from a technical standpoint I’m quite proud of it, BUT I’m not sure that it is easy to read / understand what is going on. I may be suffering too much from “I’m so kewl, look what I can do in one line of code!”, a malady that often strikes javascript and C++ programmers. But I’m so proud of my programming expertise I don’t want to get rid of it, so this is how it finally ended up in my code.
/* this next line is cool, but it may take you a moment to understand what it is doing
* it is looking for all templates that don't have any sheets associated to them
* then it is removing those templates from the collection
*/
SubsetTemplates.RemoveAll( t => Sheets.Count( s => s.SubsetVersionUid == t.SubsetVersion ) == 0 );