3

ここで質問するのが適切かどうかわかりませんが、そうでない場合は申し訳ありません。

以下と同じコードを使用します。

C# LINQ 式の質問

string[] digits = { "zero", "one", "two", "three", "four", "five", 
                    "six", "seven", "eight", "nine" };
var shortDigits = digits.Where((digit, index) => digit.Length < index);
foreach (var sD in shortDigits)
{
    Console.WriteLine(sD);
}
// Output:
// five
// six
// seven
// eight
// nine

digitシステムは、項目が数字でありindex、配列内の位置であることをどのように認識しますか?

4

4 に答える 4

6

拡張メソッドの特定のオーバーロードは、最初のパラメーターが要素で、2 番目のパラメーターがその要素のインデックスであるWherea を受け入れるように定義されています。Funcこれはドキュメントで明示的に言及されています:

述語

タイプ:System.Func<TSource, Int32, Boolean>

各ソース要素の条件をテストする関数。関数の 2 番目のパラメーターは、ソース要素のインデックスを表します

鉱山を強調します。

于 2012-07-10T16:11:19.810 に答える
2

これは単なるネーミングです。任意の桁に名前を付け、任意のインデックスを付けることができます。これは無名関数の単なるラムダ式です...次のように書き換えることができます:

(string digit, int index) => digit.Length < index

そのため、名前は、メソッドで通常設定するパラメーターと同じです。C# エンジンによって認識される名前について、特別なことは何もありません。

(string index, int digit) => index.Length < digit

上記も機能します...混乱しますが、機能します。好きな名前にできることを示すだけです

署名自体を参照している場合は、Where 関数のオーバーロードが原因です。

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate
)

したがって、この場合の TSource はstringであり、Func は になりFunc<string, int, bool>ます。ラムダはパラメーターのstring後にパラメーターを取り、値intを返す必要があることを意味しますbool

于 2012-07-10T16:11:32.767 に答える
1

使用しているオーバーロードは、次のWhereように実装されています。

public static IEnumerable<T> Where<T>(
      this IEnumerable<T> list, Func<T,int,bool> predicate)
{
   int num = -1;
   foreach (T current in list)
   {
      num++;
      if (predicate(current, num))
      {
         yield return current;
      }
   }
   yield break;
}

ご覧のとおり、反復ごとに述語 (つまり、渡されたラムダ式) が呼び出され、リストの現在の要素と現在のインデックスが渡されます。

このようにして、ラムダ式のコードは要素とそのインデックスの両方を認識します。

于 2012-07-10T16:22:51.460 に答える
0

where次のような関数を述語として取るオーバーロードがあるためです。

Func<TSource, int, bool>

この述語 ios のセマンティクスが定義されているため、2 番目のパラメーターはインデックスです。そのため、2 つの引数を持つラムダを渡すと、そのバージョンの where が呼び出されます。

于 2012-07-10T16:12:55.730 に答える