public static IEnumerable<T> Pipe<T>(this IEnumerable<T> source, Action<T> action)
{
return _(); IEnumerable <T> _()
{
foreach (var element in source)
{
action(element);
yield return element;
}
}
}
I've found this code in MoreLinq repo and can't understand this line:
return _(); IEnumerable <T> _()
This code uses a relatively new feature of C#, called local function. The only unusual thing about this function is its name: developers used a single underscore for it. Hence, the name of the function is _, so the invocation looks like this: _()
Now that you know that return statement returns the result of invoking a local function named _, the rest of the syntax falls into place:
// This is a local function
IEnumerable <T> _() {
...
}
(OP's comment on the question) Can't we just do
foreachwithyield return?
The method that you copied included two additional lines, which are key to understanding the difference:
public static IEnumerable<T> Pipe<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (action == null) throw new ArgumentNullException(nameof(action));
return _(); IEnumerable <T> _()
{
foreach (var element in source)
{
action(element);
yield return element;
}
}
}
If you put foreach with yield return directly into the body of Pipe<T> method, argument checking would be deferred until you start iterating your IEnumerable<T> result. With local function in place you would do the check as soon as Pipe<T> is called, even in situations when the caller never iterates the result.
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