Bug Report #2 - Lazy Select In C#
This is the second in a series of articles about bugs I encounter while working. The first one was about
GETUTCDATE() and how it complicates things in longer queries.
Today’s bug is about LINQ and the lazy
IEnumerables it produces. A one-off script on which I spent way too much time worked something like this:
Granted, not the most elegant code. But I thought it was enough to do it’s job. Turns out there’s a simple yet subtle bug occurring. Turns out that
Select is quite lazy, so
items is more like a promise that if you’re iterating it you’ll get the result of
Transform() applied to each element from
RawItems. But every time the iterator is used, that computation gets redone.
foreach loop actually modified each resulting element from one invocation of the iterator, but all that data was thrown away. When
items it obtained a new version of the derived data, without any of the modifications.
The solution is simple. Either include the modification as part of the
Select and alongside
Transform. Or make
items non-lazy, by turning it into an
Array, which is what I ended up doing for simplicity’s sake in my actual setup. So the code was now just:
foreach loop and
UpdateItems now referenced a list, instead of the iterator over something, the desired behaviour was achieved.