Logging inside a Linq fluent chain I've posted this to Stack Overflow, but someone voted to close as they felt it was opinion based, so I'm bringing it over to Code Review.

I have some Linq fluent chains to shape an original IEnumerable of objects into the proper form.

During this process, I'd like to capture and log the reason why some objects are "rejected" in a Where clause.

I was thinking about something similar to this (reduced use-case, just for the sake of demonstration):

var bar = SomeEnumerable
    .SelectMany(...)
    .Where(i =&gt;
    {
        if(...)
        {
            return true;
        }
        else
        {
            //Log "failure" to in-memory list
            return false;
        }
    })
    .ToDictionary(...);     


I understand that this introduces some side-effect, though minimal, but if at all possible, I would like to eliminate it.

Does this match some "pattern" that can be expressed in the context of Linq chains?

Thanks
Yeah, it seems to cloud up your code a bit. You could write your own LINQ-style extension method similar to the ones below. It uses a couple of C#7 features (tuple types and local methods). The first just recreates the collection with the results associated with each item (to avoid any side-effects of possibly calling the predicate multiple times) and the second will iterate and log/filter as your lambda does.

namespace System.Linq
{
    using System.Collections.Generic;

    public static class Enumerable
    {
        public static IEnumerable&lt;(TSource, bool)&gt; WhereResult&lt;TSource&gt;(
            this IEnumerable&lt;TSource&gt; source,
            Func&lt;TSource, bool&gt; predicate)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            return _();

            IEnumerable&lt;(TSource, bool)&gt; _()
            {
                foreach (TSource current in source)
                {
                    yield return (current, predicate(current));
                }
            }
        }

        public static IEnumerable&lt;(TSource, bool)&gt; LogWhere&lt;TSource&gt;(
            this IEnumerable&lt;(TSource, bool)&gt; source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return _();

            IEnumerable&lt;(TSource, bool)&gt; _()
            {
                foreach ((TSource, bool) current in source)
                {
                    if (current.Item2)
                    {
                        yield return current;
                    }
                    else
                    {
                        Log(...);
                    }
                }
            }
        }
    }
}


This is just a first thought off the top of my head. Could be improved easily with some AOP instead of the explicit logging call, for instance.