2017-12-27 14 views
1

私はC#7の新機能、特にローカルメソッドを試していました。私はLinq Where Operatorを書いた。C#7ローカルメソッドで新しい汎用パラメータを再導入することをお勧めしますか?

イテレータブロックをローカルメソッドとして実装しました(実際に、ローカルメソッドは非同期メソッドとイテレータの完璧なソリューションであるという記事を読んでいます)。

これらの2つの実装に違いがあるのか​​、どちらが最適ではないのだろうか?

最初の実装:ここ

は私が...パラメータのためのローカル方法、新しい名前のための新しいジェネリック型パラメータを導入

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if(source == null) throw new ArgumentNullException(nameof(source)); 
    if(predicate == null) throw new ArgumentNullException(nameof(predicate)); 
    return WhereIterator(source, predicate); 

    IEnumerable<TSequence> WhereIterator<TSequence> (IEnumerable<TSequence> localSource, Func<TSequence, bool> localPredicat) { 
     foreach(TSequence item in localSource) { 
      if(localPredicat(item)) { 
       yield return item; 
      } 
     } 
    } 
} 

第2の実施:

新しい汎用パラメータはありません。新しいpはありませんローカルメソッドは囲むメソッドの変数を取り込むことができるので、arameters。

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if(source == null) throw new ArgumentNullException(nameof(source)); 
    if(predicate == null) throw new ArgumentNullException(nameof(predicate)); 
    return WhereIterator(); 

    IEnumerable<TSource> WhereIterator() { 
     foreach(TSource item in source) { 
      if(predicate(item)) 
       yield return item; 
      } 
     } 
    } 
} 
+2

なぜWhereIteratorが必要なのかわかりません。あなたはそれを持っていなくて、Whereメソッドでforeachすることができます。 – rokkerboci

+0

デコンパイルされたソース[ここ](https://sharplab.io)をチェックすることができます。それらの機能を記述し、正しい結果を確認するだけです。 –

+0

私は確かな引数の検証が必要です:)、私はWhereIteratorメソッドを使用しない場合、引数の検証が遅れて行われます。 そのため、イテレータをローカルメソッドとして実装しました。 –

答えて

2

2番目の実装が優れています。主な違いは、第二の実装が自分自身を繰り返してからあなたを解放し、暗黙的にそのパラメータを捕獲することである:

  • パラメータの型を指定して、
  • 指定するパラメータ名、および
  • する関数に引数を渡すとき。

繰り返しを避けることは非常に重要なプログラミングの慣行なので、2番目の実装を優先する必要があります。

+1

@IvanStoevあなたが正しいです、これは完璧な意味合いです。コメントありがとう! – dasblinkenlight

+0

まさに、私たちは熱心な議論の検証が必要です。これが最初にローカルメソッドを使用した主な理由です。 私はイテレータブロックを実装するためにプライベート静的メソッドを使用する前に、ローカルメソッドを使用していたので、イテレータブロックからLinq拡張メソッドを実装するクラスを維持するのに役立ちます。 簡単に言えば、iteratorブロックは、そのメソッド内でのみ使用されるため、クラスからLinq演算子メソッドに移動するのに役立ちました。 –

+0

しかし、今私は混乱しています。私の質問は簡単です:ローカルメソッドは、囲むメソッドの外部変数をキャプチャできるという事実を使用してイテレータブロックを実装するか、またはこれを無視して新しい引数の型とパラメータを導入する必要がありますか? –

関連する問題