You don’t have to use query expressions to use LINQ

LINQ is clearly gaining a fair amount of traction, given the number of posts I see about it on Stack Overflow. However, I’ve noticed an interesting piece of coding style: a lot of developers are using query expressions for every bit of LINQ they write, however trivial.

Now, don’t get the wrong idea – I love query expressions as a helpful piece of syntactic sugar. For instance, I’d always pick the query expression form over the “dot notation” form for something like this:

var query = from file in Directory.GetFiles(logDirectory, “*.log”)
            from line in new LineReader(file)
            let entry = new LogEntry(line)
            where entry.Severity == Severity.Error
            select file + “: “ + entry.Message;

(Yes, it’s yet another log entry example – it’s one of my favourite demos of LINQ, and particularly Push LINQ.) The equivalent code using just the extension methods would be pretty ugly, especially given the various range variables and transparent identifiers involved.

However, look at these two queries instead:

var query = from person in people
            where person.Salary > 10000m
            select person;

var dotNotation = people.Where(person => person.Salary > 10000m);

In this case, we’re just making a single method call. Why bother with three lines of query expression? If the query becomes more complicated later, it can easily be converted into a query expression at that point. The two queries are exactly the same, even though the syntax is different.

My guess is that there’s a “black magic” fear of LINQ – many developers know how to write query expressions, but aren’t confident about what they’re converted into (or even the basics of what the translation process is like in the first place). Most of the C# 3.0 and LINQ books that I’ve read do cover query expression translation to a greater or lesser extent, but it’s rarely given much prominence.

I suspect the black magic element is reinforced by the inherent “will it work?” factor of LINQ to SQL – you get to write the query in your favourite language, but you may well not be confident in it working until you’ve tried it; there will always be plenty of little gotchas which can’t be picked up at compile time. With LINQ to Objects, there’s a lot more certainty (at least in my experience). However, the query expression translation shouldn’t be part of what developers are wary of. It’s clearly defined in the spec (not that I’m suggesting that all developers should learn it via the spec) and benefits from being relatively dumb and therefore easy to predict.

So next time you’re writing a query expression, take a look at it afterwards – if it’s simple, try writing it without the extra syntactic sugar. It may just be sweet enough on its own.

14 thoughts on “You don’t have to use query expressions to use LINQ”

  1. A new developer recently joined the team I work for and explained me he did not like Linq because he does not trust what’s running behind the curtain.
    He does not like declarative programming either (attributes…) and prefers to have everything ‘under control’ imperatively.

    I think you get much more confidence in a technology when you start understanding it rather than just knowing it. This is the main reason why I like books such as “C# in depth”, they allow me to understand how things work and not just write the code from the book blindly.

    Three things I’m sure about still
    Parts of my code are really clearer with Linq and I really miss it when I need it on <3.5 projects
    Other developers from other environments to whom I show Linq (to objects and entities) find it really neat
    Never forget someone else might have to read your code in the future…

  2. I agree, I see a fair amount of the more verbose syntax from fellow developers for such simple queries and at a glance (at least to me) the intention isn’t as clear.

    I tried to +1 but I couldn’t find the vote button. Oh yeah this isn’t SO.

  3. Wow, it’s the exact opposite for me, where query expressions seem like black magic, whereas a method call seems understandable.

    I could use that aspect without reading any documentation outside of intellisense, yay for discoverablility. :)

    Of course I don’t know SQL, and only use LINQ to Objects.

  4. I think some of this is from the fact that alot of developers introduction to LINQ is through LINQ to SQL examples. I think this sometimes leads some developers to write all LINQ code like they would an SQL statement.

  5. Agreed. Add to that the number of overloads and additional methods (both standard and bespoke) that can *only* be called through dot syntax.

    From what I’ve seen, people with too much query-syntax affinity regularly miss out on a simple, elegant way to do something simply because query-syntax can’t express it. Even simple *core* things like Skip/Take.

  6. Thanks Marc

    Usually I just need to maintain the application and try to respect the same coding techniques as for the rest of the application.
    I’d love to change all those FindAll(delegate) but it is not worth the effort

  7. As you say it depends on the complexity, but pretty simple ones still sometimes look better with the sugar. For example take the following which has a mix of styles:

    return (from d in descendants where d.Key == descendantKey select d.Value).Single();

    in dot notation:

    return descendants.Where(d => d.Key == descendantKey).Select(d => d.Value).Single();

    Either works for me, but I’m pretty sure the first is more readable to all skill levels of LINQ.

    Marc has a great point in that anything outside the sugar can easily be missed if you rely on it… I’m thinking perhaps I should always code in dot notation first and if ugly see if I can then sugar it, rather than the other way around.

  8. I agree. This could be a perfect refactoring tip in ReSharper.
    Today (for example) it suggests to invert “if” statements, if it can make the code shorter and less indented.
    It could easily find LINQ expressions that could be shortened by their equivalent query expressions, and offer to convert them for you.
    JetBrains: The ball is in your court :-)

  9. I’ve heard Luke Hoban saying that query expressions were introduced in C# because the learning curve for LINQ still was quite high.

    And to that point, I’m really interested in the percentage of those who use expressions (“from .. in .. select ..”) among the whole bunch of us using LINQ.

    Cause from what I can see, it’s just a tiny fraction of “expressionists”. Maybe it could have been a wiser choice to introduce LINQ and *then* consider changing the language??

    Just curious. I might be wrong, of course.

  10. It’s funny, I originally used query expressions because they were so heavily advertised and they had a certain novelty. Nowadays, I often forget they even exist. I use LINQ all the time, but I virtually never use query expressions unless I really need to declare an intermediate with ‘let’. Once you get comfortable with the standard LINQ operators, you can leverage the framework much more effectively (and often more efficiently) using the extension methods.

  11. It is interesting that most of the usages in LINQ (>90%$) use the sugar free syntax. It just seems more natural in many situations. It could be that for a C# developer there is less of an impedance mismatch when you look at the traditional syntax over a query expression.

    I certainly find I have to think a little harder about LINQ which is written using the expression syntax.

  12. @Jon,
    A first “query expression” example, with its two “from” lines one after another, looks surprisingly similar to Scala for expression syntax. Inside Scala’s “for” you can also do it: select files from a directory, select lines from files, filter results and then use it inside {} block of “for”. That’s one of examples in “Programming in Scala” http://booksites.artima.com/programming_in_scala

Comments are closed.