The Weekly Source Code 19 - LINQ and More What, Less How
Dear Reader, I present to you nineteenth in a infinite number of posts of "The Weekly Source Code."
At Mix, Clint Rutkas and I were messing around writing a plugin model for one of his apps. We were prototyping and I typed up this typical-looking plugin style code:
string[] filesToTest = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll"); foreach (string file in filesToTest) { Assembly a = Assembly.LoadFrom(file); foreach (Type t in a.GetTypes()) { if (!t.IsAbstract && t.BaseType == typeof(MyBaseClass)) { myListOfInstances.Add((MyBaseClass)Activator.CreateInstance(t, credentials)); } } }
It's pretty straightforward and has little (read: no) error handling. It spins through the DLLs in the /plugins folder, loads them each (this should be more explicit rather than a blanket load of all dlls in a folder), then looks for any types that are derived from MyBaseClass that aren't abstract, then instantiates them and puts them in a list.
I'm going to quote Jeff Moser's very good blog post "What does it take to be a grandmaster" in both this post and the next one I write. It's that good. Seriously, go read it now, I'll wait here.
Jeff invokes Anders Heilsberg (Father of C# and LINQ) and:
"Anders' recent statement that future versions of C# will be about getting the programmer to declare "more of the what, and less of the how" with respect to how a result gets computed. A side effect of this is that your "chunks" tend to be more efficient for the runtime, and more importantly, your brain."
I'm going to repeat part I bolded. I like Programming Languages that allow me to declare "more of the what, and less of the how." This how we tried to design the system at my last job and I automatically mentally migrate towards systems that encourage this kind of thinking.
So, back to the foreach loops above. My good friend (and fellow baby sign language fan) Kzu came by while Clint and I were working and suggested we turn this increasingly complex procedure into a LINQ query.
After a few tries, here's what we came up with.
myListOfInstances = (from file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll") let a = Assembly.LoadFrom(file) from t in a.GetTypes() where !t.IsAbstract && t.BaseType == typeof(MyBaseClass) select (MyBaseClass)Activator.CreateInstance(t, credentials)) .ToList();
This is all one line, with some whitespace for readability. It says the same thing as the first chunk of code, but for some minds, it might be easier to read. This isn't a very good example of LINQ shining, from my point of view even though I like reading it. Certainly there's nowhere (I can see) for me to put error handling code that catches a bad load or bad cast in this example. There are, however, a LOT of places within that single line that one could set a breakpoint.
A better example would be like the one Jeff uses:
var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 };
var primeSum = 0;
for (int i = 0; i < primes.Length; i++)
{
primeSum += primes[i];
}
...or even...
var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 }; var primeSum = 0; foreach (int i in primes) { primeSum += i; }
...could be more easily written and read like:
var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 }; var primeSum = primes.Sum();
where .Sum() is part of LINQ as Arrays are IEnumerable.
I totally recommend you go get the free, no-installer LINQPad that comes with 200 examples from C# in a Nutshell.
Here are a few examples that I think really typify pretty code; certainly an improvement over the standard procedural code I'd usually write:
var names = new[] { "Tom", "Dick", "Harry" }.Where(n => n.Length >= 4);
Here's onen that does quite a few things to a list in a fairly clean syntax:
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; var results = ( from n in names where n.Contains("a") // Filter elements orderby n.Length // Sort elements select n.ToUpper() // Translate each element (project) ).ToList();
What LINQ-style queries have you written that feel more what than how?
Related, ahem, LINQS
- LINQ to Everything - LINQ to XSD adds more LINQiness
- Get namespaces from an XML Document with XPathDocument and LINQ to XML
- Moq: Linq, Lambdas and Predicates applied to Mock Objects
- Hanselminutes Podcast 79 - LINQ to XML
- Improving LINQ Code Smell with Explicit and Implicit Conversion Operators
- XLINQ to XML support in VB9
- 101 LINQ Samples
- LINQ to Amazon
- How Linq to Object Queries Work
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.



About Newsletter