The Linq “let” keyword

Writing

I’ve been busy working on some presentations that I have coming up, and so I haven’t had too much time to update, but I was messing around with Linq and I found myself using the “let” keyword quite a bit to make some of my queries more readable. So I decided to do a small write-up so that you can see the joy of using the “let” keyword.

Lets say we have a small set of data that looks like this:

var nameList = new List<string>
                   {
                       "Matt",
                       "Adam",
                       "John",
                       "Peter",
                       "Owen",
                       "Steve",
                       "Richard",
                       "Chris"
                   };

And we have a method where we need to return a list of names that start or end with vowels and are either 4 or 5 characters long. So, our inexperienced Linq developer quickly codes up a query that looks like this (yes, I know the “ToUpper” is ugly, but I’m not changing it now 🙂 ):

var vowels = new List<string> {"A", "E", "I", "O", "U"};
var names = (from p in nameList                                                  
            where
            (vowels.Any(v => p.ToUpper().StartsWith(v)) 
            || vowels.Any(v => p.ToUpper().EndsWith(v))) &&
            (p.Length == 4 
            || p.Length == 5)
            select p).ToList();

First we have to define our List of vowels, since we are using it twice. Then we code up our query just like we would if we were writing a sql statement. The only problem is that by just looking at this query it is pretty hard to tell what it is doing. But what if we had a way to break up the query so that we could make its purpose more clear? Well, thankfully we do!

var names = (from p in nameList
            let vowels = new List<string> { "A", "E", "I", "O", "U" }
            let startsWithVowel = vowels.Any(v => p.ToUpper().StartsWith(v))
            let endsWithVowel = vowels.Any(v => p.ToUpper().EndsWith(v))
            let fourCharactersLong = p.Length == 4
            let fiveCharactersLong = p.Length == 5
            where
            (startsWithVowel || endsWithVowel) &&
            (fourCharactersLong || fiveCharactersLong)
            select p).ToList();

Now, doesn’t that look better? We define four intermediate variables that hold our vowels and booleans for our tests, then in the where clause we just check our boolean values. The result is a where clause that is very readable. There are tons more uses for “let”, but I hope that you start using it in your queries to make them more readable.

More Insights

View All