1

友人が次の Linq ステートメントを見せてくれました。

records.Where( r => r.Name == "Henry Clay" ).FirstOrDefault();

FirstOrDefault() がラムダを受け取ることができるという事実は別として、すべての Henry Clay レコードが FirstOrDefault() に移動する前に「Henry Clay」をチェックしますか、それとも Where メソッドは最初のレコードを返すだけですか?

言い換えれば、一部の Henry Clay レコードが FirstOrDefault に渡されない可能性はありますか?

4

2 に答える 2

5

最後の最後の前にアイテムを見つけたとすると、ソースシーケンス全体を繰り返すことはありません。最初のアイテムが返されるとすぐに停止します。

これは有用な例えです。テーブルに隣同士に座っている人々のグループを想像してみてください。「マイク」は左端に座っています。彼の隣の人が彼にアイテムを求めるときはいつでも、彼はスタックから一枚の紙をつかみ、それを次の人に渡します。彼は、基になるデータの「列挙子」になりますrecords

彼の隣に座っているのは「フレッド」です。フレッドは、アイテムを求められると、マイクにアイテムを求めます。マイクが彼に与えるアイテムに「ヘンリークレイ」と書かれている場合、彼は次の人にそれを渡します。そうでない場合、彼はマイクに別のアイテムを要求します。これは、フレッドが最終的に彼の条件を満たすアイテムを取得するか、マイクがアイテムを使い果たすまで続きます。彼はWhere列挙者を代表しています。

フレッドの右側には「アーロン」があります。アーロンは、アイテムを求められると、フレッドにアイテムを求めます。フレッドからアイテムを受け取ったら、次の人に渡します。次に誰かがアイテムを要求すると、フレッドに何も要求せずに、すぐに「いいえ、もう完了しました」と言います。彼は代表していFirstOrDefaultます。

各人は、隣の人からアイテムを求められた場合、求められた場合にのみ、「ソース」からアイテムを取得し、処理するか、必要なことを実行して、次の人のアイテムを生成します。この例を使用すると、アーロンが最初のアイテムを取得すると、スタックに紙が残っている可能性が非常に高いことが想像できます。アーロンがフレッドに2番目のアイテムを要求することは決してないので、彼らはにも処理されずにそこにとどまります。

于 2012-10-29T20:29:24.787 に答える
5

いいえ、すべての要素が遅延して実行されます。これは、クエリを次のように書き直すとわかります。

records.Where(r =>
{
    Console.WriteLine(r.Name);
    return r.Name == "Henry Clay";
})
.FirstOrDefault();

ToArray()たとえば、次のように実行を強制すると、結果は大きく異なります。

records.Where(r =>
{
    Console.WriteLine(r.Name);
    return r.Name == "Henry Clay";
})
.ToArray()
.FirstOrDefault();

最後のケースでは、コレクションToArray()内のすべての要素の反復を強制しますが、それ以外の場合は、where 述語が最初に true を返した後にコレクションの反復が停止されるようにします。recordsFirstOrDefault()

于 2012-10-29T20:30:08.967 に答える