I’m currently writing about readability, and discussing deferred parameter evaluation in LINQ on the C# newsgroup. It’s led me to come up with quite an evil application of captured variables.
Consider this C# 3 code:
values variables are easy enough to understand, and the
foreach loop at the bottom just iterates through the query and dumps out the results – but what does the query itself do?
The answer is that it shows you all the values which are larger than any that have come before it. Each value encounters the “where” clause which is effectively “are you the biggest value I’ve seen so far?” and passing values then encounter the “select” clause which is “remember the current value as the highest we’ve seen, and return it”. So, the output is 0, 5, 8, 10, 12, 100.
It relies on the fact that the “select” clause for one passing value is executed before the next “where” clause. If you force it to evaluate the “where” clause for all the source values before performing the projection (e.g. with an “orderby” clause) then all the numbers are returned, because they’re all bigger than the initial value of
max. If you try to use Parallel LINQ to evaluate it, all bets are off.
Contrary to the normal advice, do try this at home. Just don’t try it in production code. (If you find a genuine use for it, at least comment it heavily!)