I had a look at the implementation of several extension methods of the genious MoreLINQ- project. And I came across a style habit that I cannot explain. Maybe some of you can?
It happens for example in Pairwise.cs, cited below.
So why would the author author a local function named _() just to call it in the return expression? Wouldn't it be straight forward just to implement the yield return/yield break in the very function? My suspicion is that it has something to do with the way the compiler generates the Enumerator-object off the yield implementation. But I don't see a difference. Actually there is even some closure-ing happening - I regard that as even worse (!?)
Edit: No, it should not be closured, because it is not a lambda but a local function which will just grab the outer scope variables whatever they are.
public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TSource, TResult> resultSelector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
return _(); IEnumerable<TResult> _()
{
using (var e = source.GetEnumerator())
{
if (!e.MoveNext())
yield break;
var previous = e.Current;
while (e.MoveNext())
{
yield return resultSelector(previous, e.Current);
previous = e.Current;
}
}
}
}
It's to make argument validation eager but allow the rest of the method to be written using yield. With it, you get an exception relating to the arguments at the point at which you call Pairwise<TSource, TResult>.
Without it, you'd get the exception when you first call MoveNext on the returned enumerator.
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