In the C# code below, I found the usage of _() strange. Can anyone explain what this means?
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
            Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
    return _(); IEnumerable<TSource> _()
    {
        var knownKeys = new HashSet<TKey>(comparer);
        foreach (var element in source)
        {
            if (knownKeys.Add(keySelector(element)))
                yield return element;
        }
    }
}
                The code might be more easily understood by inserting a line break after the return statement:
return _();
IEnumerable<TSource> _()
{
    var knownKeys = new HashSet<TKey>(comparer);
    foreach (var element in source)
    {
        if (knownKeys.Add(keySelector(element)))
            yield return element;
    }
}
In this context, the underscore is just an arbitrary name for a local function (which is a new feature introduced in C# 7.0). If you prefer, you could replace the underscore by a more descriptive name:
return DistinctByHelper();
IEnumerable<TSource> DistinctByHelper()
{
    var knownKeys = new HashSet<TKey>(comparer);
    foreach (var element in source)
    {
        if (knownKeys.Add(keySelector(element)))
            yield return element;
    }
}
As a local function, the _ (or DistinctByHelper) method can access all the variables of the DistinctBy method.
By the way, the reason for having two methods here is so that, in case any argument is null, ArgumentNullException will be thrown immediately when DistinctBy is called instead of when the result is enumerated (due to the presence of the yield return statement).
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