LINQ, Lambda and the Learning Curve

3. January 2010

Been away for a while working on a 107,000 hour project. It isn?t done, but I am making time to blog and do my technical mentorship, because I have come to realize that there will always be high priority projects. You have to take the time to train and mentor during those projects because of that. Now on to the show.

I know that LINQ has received a massive welcome from the community and I have to say that it is a deserved on. On the whole it is a great addition to the language. I however don?t like one part of it. Verbose LINQ. I realize that it is more SQL like and that it is perceived to  shorten the learning curve, but I disagree. Lambdas are where the true power of LINQ sit and using verbose to me seems to focus you to learn LINQ one way so that you can re-learn it another.

I am going to focus on the Lambda side of LINQ simply out of preference. Keep an eye out here for the verbose VS. lambda death match, but that is a post for another time.

Lambda statements are actually fairly simple once you break them up.

SomeList.Where(c=>c.Id == someInt);

The above is the lambda conversion of this code block

foreach (Item item in SomeList)
{
    If(item.Id == soemInt)
        SomeOtherList.Add(item);
}

Lets break down the lambda so that this is a bit more clear.

c =>

This statement is declaring that the item in the list we are looking at is going to be held in the local variable named ?c?. This is no different than naming the variable in a for each loop ?c?. You can name your lambda variables more intuitively and I would encourage you to do so. Something like this.

SomeList.Where(menuItem => MenuItem.Id == someInt);

Once the object is declared you have the ability to use all of the members of that object. That is how we are able to use the ?Id? property to check something for a Boolean property. Selecting based on some Boolean expression is the most common use for Lambdas but not the only one.

List<SubMenu> submenus = SomeList.Select(menuItem => new SubMenu() 
                                                   {
                                                         ParentMenuId = menuItem.Id 
                                                   });

In this example we have created a submenu item from all the menu items in the list. We did this through the power of LINQ to let use change the output type of the selection at will. This is very usefull when you are creating items from other items. The code block that would represent is:

List<SubMenu> SubMenus = new List<SubMenu>();

foreach(MenuItem item in SomeList)
{
    SubMenu subMenu = new SubMenu();
    subMenu.ParentMenuId = item.Id;
    SomeOtherList.Add(subMenu);
}

To me this power is amazing. I have the ability to replace entire loops with a single line. The hit to readability is a concern but lambdas lend themselves to so many applications, and are key to LINQ so it should be part of the core toolset of a developer. If you use some sense and name your lambda variables intuitively you should get a lot of great millage out of LINQ without losing your readability.

C#, C# Helpful Functions, .NET

Test Driven Development ? Not for the faint of heart.

10. September 2009

I started coding in C# about a year ago and almost immediately found that once I had completed a project I wanted to go back and streamline and improve it. When time allowed I started trying to do this and found that the code was very hard to verify functionality. I also found that some of my design choices were pretty novice, due to that the code was very hard to enhance. 
I got introduced to the idea of test driven development by a good friend Rob Tennyson. He presented on the topic at the Tyson Foods internal .NET user group. This peaked my interest for two reasons. One, It would allow for avoiding the novice mistakes in design and class layout. Two, it would allow for my code to have automated verification of functionality.
I set out to work TDD into my everyday process and hit several brick walls.
1. You end up making things public for testing that should not be otherwise, or putting test code into the finished product (neither is a workable solution in my book). I am using NUnit and I didn't want to have a reference to a testing package in my production code. Adding a dependency to the production code that other developers will have to deal with was not my idea of a stable codebase.
2. Being a beginner in TDD as well as C# I didn't know what I didn't know so by that lack of code and language knowledge I repeated some novice mistakes in design. Not as many as before but still a few. Some would argue that I gained knowledge and that is why I see those bottlenecks and design issues more clearly and to that my only reply is "yeah prolly".
3. Abstraction is a premium but sometimes too much work. I write a lot of small applications, an editor here, a website there. While I do work to abstract a lot of my code and provide interfaces in the right places for a small application putting in the level of seams needed for proper TDD would be building an elevator in an outhouse.
4. I found it increasingly difficult to find answers in my hunt for TDD utopia. I read several books on the subject and found that I was more often than not provided with contradictory rules to apply, or methods to use. Microsoft's "Test-Driven Development in Microsoft .NET" by James W. Newkirk and Alexei A. Vorontsov gave great baseline examples and presented the basics of TDD very well, however it fails to provide good solid base for TDD in the real world. The application that they base a lot of their examples around ignores some fairly large aspects of the TDD mindset like separation of integration testing and design testing.

With the miles behind me and a TDD utopia still nowhere in sight I have found several good ideas.

1. Kent Beck's TDD by Example is a great resource for TDD on the intermediate to advanced level.

2. Not everything needs to be designed using TDD, some things are just too trivial.

3. TDD is a design pattern, and it should be used as such. If you want automated testing use automated tests, but if you want TDD programs before one line of code is written have a test list and priority assigned to them.

I am working on a TDD project currently with Jay Smith and Rob Tennyson to write a checkers application using only TDD and having no UI or Data Layer. Building Logic first, then the UI, and finally adding a data layer to detail how to handle those real world integration concerns.

Just Remember Code like you have to support it.

C#, .NET, Productivity, Unit Testing, Design Patterns