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