Search code examples
c#linqside-effects

Is it bad practice to purposely rely on Linq Side Effects?


A programming pattern like this comes up every so often:

int staleCount = 0;

fileUpdatesGridView.DataSource = MultiMerger.TargetIds
    .Select(id =>
    {
        FileDatabaseMerger merger = MultiMerger.GetMerger(id);

        if (merger.TargetIsStale)
            staleCount++;

        return new
        {
            Id = id,
            IsStale = merger.TargetIsStale,
            // ...
        };
    })
    .ToList();

fileUpdatesGridView.DataBind();
fileUpdatesMergeButton.Enabled = staleCount > 0;

I'm not sure there is a more succinct way to code this?

Even if so, is it bad practice to do this?


Solution

  • No, it is not strictly "bad practice" (like constructing SQL queries with string concatenation of user input or using goto).

    Sometimes such code is more readable than several queries/foreach or no-side-effect Aggregate call. Also it is good idea to at least try to write foreach and no-side-effect versions to see which one is more readable/easier to prove correctness.

    Please note that:

    • it is frequently very hard to reason what/when will happen with such code. I.e. you sample hacks around the fact of LINQ queries executed lazily with .ToList() call, otherwise that value will not be computed.
    • pure functions can be run in parallel, once with side effects need a lot of care to do so
    • if you ever need to convert LINQ-to-Object to LINQ-to-SQL you have to rewrite such queries
    • generally LINQ queries favor functional programming style without side-effects (and hence by convention readers would not expect side-effects in the code).