2017-08-28 15 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方法のすべての変数にアクセスすることができます。ところで

は、ここでは2つのメソッドを持つ理由は、いずれかの引数がnullの結果は(列挙されたときの代わりに呼び出されたときにDistinctByArgumentNullExceptionが原因yield returnの存在にすぐにスローされます場合にはそう、ということですステートメント)。

+4

私は本当にこのパターンがつかまないことを願っています。それはちょうど醜いです。 –

+0

ローカル関数がどのような種類の識別キーワードをも欠いていることは決してありませんでした。例えば、ローカルデリゲートやオブジェクトイニシャライザリストでは混乱しやすいでしょう。単純な 'func'キーワードまたは必須のラムダ構文' => 'が役立ちます。 – Dai

+0

ローカルの機能はここでは必要ありません。 –

関連する問題