I have the code
Enumerable.Range(100, 100)
.Select(x => x / 10)
Is there a way I can pass the line .Select(x => x / 10) to a method. The intention is to pass the results to a method as the select happens. I want to avoid a foreach here.
You could write your own extension method which performs an action on each item as it passes through:
public static IEnumerable<T> WithAction<T>(this IEnumerable<T> source,
Action<T> action)
{
foreach (T item in source)
{
action(item);
yield return item;
}
}
Then depending on whether you wanted to act on the original value or the projected one, you'd write:
Enumerable.Range(100, 100)
.Select(x => x / 10)
.WithAction(x => Console.WriteLine(x))
or
Enumerable.Range(100, 100)
.WithAction(x => Console.WriteLine(x))
.Select(x => x / 10)
This keeps it independent of the Select
itself. If you need it to make use of the projection, you could potentially write something like:
public static IEnumerable<TResult> SelectAndAct<TSource, TResult>
(this IEnumerable<TSource> source,
Func<TSource, TResult> projection,
Action<TSource, TResult> action)
{
foreach (TSource item in source)
{
TResult result = projection(item);
action(item, result);
yield return result;
}
}
Then:
Enumerable.Range(100, 100)
.SelectAndAct(x => x / 10,
(x, y) => Console.WriteLine("Was: {0}; Now: {1}", x, y))
Note that all of this violates the normal intention of LINQ to be side-effect-free. It's not generally a good idea to have side-effects in queries... but of course there are exceptions to every rule :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With