Today was another time where I realized a drawback of LINQ Expressions (the same goes for Lambda). They are pretty as long as they represent a simple and straight forward functionality. If there’s a bug, it’s simple to find it but if the expression consists of two or more nested expressions, it becomes awkward in case of an error. To give you an example of what I mean just take a look at the LINQ expression in Golo Rodens’ MicroKernel implementation:
mappings =
(XElement.Load(file).Element("mappings").Elements("mapping")
.Select(mapping => new KeyValuePair<Type, Type>(
Type.GetType(mapping.Attribute("contract").Value),
Type.GetType(mapping.Attribute("type").Value)))).ToDictionary(
kvp => kvp.Key, kvp => kvp.Value);
No offence Golo, it could have hit anyone. It’s pure incidence it just happened when I stumbled over your work. ;-)
There’s nothing wrong with that code but it happened to me that I got a NullReferenceException when I ran this code in conjunction with a custom type in the XML config file. I had a pretty hard time to figure out where exactly the error came from. LINQ/Lambda Expressions cannot be debugged step by step. They are handled as one big function – one step in and that’s it.
So I dismantled the whole thing into elementary pieces of code and ran unit tests against them. After all and 8 (in words: EIGHT!) separate unit tests I finally found the bug.
Now when I reflect my experience I think that convoluted Expressions like the one above are not really a good thing. Yes they look pretty smart but after all I think it’s better to split these into smaller pieces. The benefits are better readability (think of CCD) and testability.