1

次の呼び出しがフィールドに加えられた変更を覚えていないように見えることを発見したのは驚きでした。

private void Foo(IEnumerable<Blopp> blopps)
{
  foreach (Blopp blopp in blopps)
    blopp.SomeField = PREFIX + blopp.SomeField;

  String test = blopps.First().SomeField;
}

LINQ to dataを使用して配列を取得する場合、テスト変数にはプレフィックスがありません。フィールドへの変更を維持するには、 IEnumerableを評価してリストにする必要があります。なんでそうなの?プログラムは、フィールドが後で使用されていることを認識し、それを評価することを期待します。

private void Foo(IEnumerable<Blopp> _blopps)
{
  List<Blopp> blopps = _blopps.ToList();
  foreach (Blopp blopp in blopps)
    blopp.SomeField = PREFIX + blopp.SomeField;

  String test = blopps.First().SomeField;
}
4

1 に答える 1

8

それはあなたがそれに何を渡すかによって異なります。遅延評価された sequence の場合、 を「見る」たびにblopps、入力が再評価されます。

のようなものを渡すとList<T>、シーケンスには毎回まったく同じ値が含まれるため、問題ありません。マテリアライズされていないクエリを渡すと、入力を見るたびにクエリが実行されます。それが前の評価と同じオブジェクトへの参照を返すかどうかは、それが何をしているかに依存します。

(コメントで述べたように、場合によっては、1 つの評価で返されたオブジェクトを変更すると、クエリの結果が完全に変更されることさえあります。オブジェクトは、クエリの前の方のフィルターと一致しないように変更される可能性があります。 )

于 2013-01-16T14:50:53.970 に答える