2016-06-23 2 views
3

私に(私にとって)奇妙な動作が発生しました。ここでは、コードは次のとおりです。含まれる要素のコピーを生成するLinq-QueryがtoList()と呼ばれていますか?

var objects = from i in items 
       //some calculations 
       select something; 

// other calculations 

objects.ToList().ForEach(x => { 
    //some calculations 
    x.Property = "some text" 
}); 

return objects; 

まず私はIEnumerableを生成し、それは私が詳細をスキップし、DBへのクエリです。 それから私は他の計算をしなければなりません。最後に私のオブジェクトを繰り返し処理して、さらなるパラメータを設定します。このコードを実行すると、IEnumerableオブジェクトが返されると、Propertyは設定されません。私は、LINQの式でToList()を移動した場合

は、そうでない場合は以下のように、Propertyが設定されている:

var objects = (from i in items 
       //some calculations 
       select something).ToList(); 

// other calculations 

objects.ForEach(x => { 
    //some calculations 
    x.Property = "some text" 
}); 

return objects; 

として、私の知る、オブジェクトは右...コピーされますが、参照されていませんか? コードの背後には何が起こりますか?違いはなんですか?

+0

[ToList()の複製 - 新しいリストを作成しますか?](http://stackoverflow.com/questions/2774099/tolist-does-it-create-a-new-list) –

+2

'objects.ToList()'を実行すると、クエリが実行されます。そして 'オブジェクト 'を返します。だれかが返されたオブジェクトを繰り返し処理するとしましょう:この場合、クエリは再度実行されるので(新しいオブジェクトが作成されます) –

+5

'ToList'を持たない' var objects'は単なるクエリなので、定義は実行されません。たとえば、 'ToList'や' forach'を使って実現すると、それが実行されます。したがって、 'ToList'を追加することによってデータベースが照会され、メモリ内のリストが埋められます。 'List.ForEach'はそれらを列挙し、プロパティを変更します。最初のアプローチでは、このリストは変数に格納されていないため、すぐに破棄されます。 2番目のバージョンは正しいです。 –

答えて

6

は、LINQクエリがちょうどクエリであることを忘れないでくださいToArrayなど)

違いは、あなたが最初の例ではToListによって返さリストをキャプチャじゃないです。それはForEachコールで使われていますが、objects変数は、まだ元のクエリへの参照を保持しています。再度尋ねると、再びデータをフェッチします。データを再度フェッチすると、新しいオブジェクトが作成されます。

その点で - はいToList()は新しいリストを作成します。 を変更しても、それをリストにするために呼び出されたオブジェクトはありません。

あなたの第二の例ではobjects変数はToList()を経由して、クエリから生成されたので、あなたがそれらを変更し、あなたは同じリストを返すしているobjects戻ったときリストへの参照を保持しています。

+2

@Taemyr私はあなたが理解していないと思う。 DStanleyと私が答えに書いたことはまさに何が起こっているのかです。 – rinukkusu

+0

@Taemyr私はそれを再度読みます。ありがとう。 –

+0

@DStanley最初の編集が大幅に改善されました。私は新しい項目が選択によって作成されることを明示的にする答えを好むでしょうが。 – Taemyr

0

最初のコードサンプルでは、​​objects.ToList()は実際にForEachで作業しているタイプListの新しいオブジェクトを作成しています。 ForEachが完了した後も、あなたはまだあなたのIEnumerableを返しています。実際に戻したいリストはなくなります。

object変数にToList()というLINQクエリを割り当てることで、ForEachに新しく作成されたリストが使用されています。 、それはどのようなデータを保持していない、それは私がこのデータを要求した場合、ここで私はwant_ものだ」と言っているが、あなたは結果を得るためask_までToListforeach経由(待機 - 。

+0

私はあなたがそのポイントを逃すと思います。リスト内の欠落しているオブジェクトへの変更。 – Taemyr

+1

正確には、彼は 'IEnumerable'を返すので、最初のサンプルに' ToList() '呼び出しの結果リストを格納しません。 – rinukkusu

+1

@Taemyrこれの鍵は、 'IEnumerable'が' IQueryable'である可能性が高いということです。これは基底のデータが変更可能なオブジェクトではなく、各繰り返しでDBから照会されるデータを意味します。 – juharr

関連する問題