2017-08-28 93 views
7

在下面的C#代码中,我发现_()的用法很奇怪。谁能解释这是什么意思?语法的含义:return _(); IEnumerable <TSource> _()

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; 
     } 
    } 
} 

回答

9

的代码可能会被return语句后插入一个换行符可以更容易理解:

return _(); 

IEnumerable<TSource> _() 
{ 
    var knownKeys = new HashSet<TKey>(comparer); 
    foreach (var element in source) 
    { 
     if (knownKeys.Add(keySelector(element))) 
      yield return element; 
    } 
} 

在这种情况下,下划线仅仅是一个local function任意名称(这是一个新的功能在C#7.0中引入)。如果你愿意,你可以通过一个更具描述性的名称替换下划线:

return DistinctByHelper(); 

IEnumerable<TSource> DistinctByHelper() 
{ 
    var knownKeys = new HashSet<TKey>(comparer); 
    foreach (var element in source) 
    { 
     if (knownKeys.Add(keySelector(element))) 
      yield return element; 
    } 
} 

作为本地功能,_(或DistinctByHelper)方法可以访问DistinctBy方法的所有变量。

顺便说一句,这里有两种方法的原因是,在情况下,任何一个参数为null,ArgumentNullException将立即在DistinctBy被调用时,结果被枚举(而不是由于yield return的存在而抛出声明)。

+4

我*真的*希望这种模式不赶上。这只是丑陋的。 –

+0

我从不喜欢本地函数如何缺少任何类型的标识关键字 - 例如,它们很容易被混淆为本地代理或对象初始化列表。一个简单的'func'关键字或强制lambda语法'=>'会有帮助)。 – Dai

+0

无论如何,本地功能似乎没有必要。 –

相关问题