5

System.Linq.Enumerable.WhereListIteratorとSystem.Linq.Enumerable.WhereSelectListIteratorの違いは何ですか?

私が気付いた違いの 1 つは、タイプ WhereListIterator はコレクション オブジェクトの変更を反映しますが、Wh​​ereSelectListIterator は反映しないことです。

たとえば、より明確にします。

リポジトリからドメイン オブジェクトを取得するシナリオがあります

var buckets = testRepository.GetBuckets(testIds);

次に、ループ内で上記のコレクションから特定のバケットを選択します

 var bucketsForTest = buckets.Where(bucket => bucket.TestID == test.testId);

次に、LooserTrafficDisributor オブジェクトのメソッド内のすべてのバケット オブジェクトの 1 つのプロパティを変更します。

ITrafficDistributor distributor = new LooserTrafficDisributor(bucketsForTest);

IEnumerable<Bucket> updatedBuckets = distributor.Distribute(test.AutoDecision);

LooserTrafficDisributor のコンストラクター

  public LooserTrafficDisributor(IEnumerable<Bucket> allBuckets)
    {
        this.allBuckets = allBuckets;
    }

LooserTrafficDistributor内のdistributeメソッドは次のようになります

 private IEnumerable<Bucket> DistributeTraffic(bool autoDecision)
 {
  // allBuckets is class variable in LooserTrafficDistributor object which is set through constructor shown above .
  // Omitted other details

                allBuckets.Where(bucket=> bucket.IsControl == false).ToList()
                    .ForEach(bucket => bucket.TrafficPercentage += 10 ));
return allBuckets
 }

この後、IEnumerable updatedBuckets コレクション内に反映された変更を確認できます。

しかし、これを行うと、つまり、リポジトリからバケット コレクションをフェッチする代わりに、次のように、すべてのバケット オブジェクトを選択して更新します。

 var bucketsForTest = testRows.Where(testrow => testrow.url == url.url).Select(currRow => new Bucket
    {
                TestID = currRow.TestId,
                    BucketID = currRow.BucketId,
                    BucketName = currRow.c_bucket_name,
                    TrafficPercentage = Convert.ToInt32(currRow.i_bucket_percentage),
                    IsControl = currRow.b_is_control,
                    IsEnabled = currRow.b_enabled,
                    UpdatedAdminId = currRow.i_updated_admin_id,
                    LogAsSection = currRow.i_log_as_section
             }) ;

  ITrafficDistributor distributor = new LooserTrafficDisributor(bucketsForTest);

  IEnumerable<Bucket> updatedBuckets = distributor.Distribute(test.AutoDecision, strategy.GetStatisticallySignificantLoosingBucketIds());

IEnumerable updatedBuckets コレクション内に反映された変更を取得できません。実際、DistributeTraffic メソッド内でデバッグを行ったにもかかわらず、各ループ ラウンド後に変更が反映されませんでした。

4

1 に答える 1

4

.Where()where基準を満たすすべての要素を含むアイテムのIEnumerableを作成します。その結果セットに対してを実行する.Select()と、選択ステートメントで作成した新しい要素の IEnumerable が取得されます。そのため、元の要素への変更は新しい要素には反映されません。

あなたの例では、元のリストのすべてのバケットを作成して、where 基準を満たす新しいバケット オブジェクトを作成し、コンテンツを元のバケットから新しいバケットにコピーします。

于 2011-10-25T11:20:48.173 に答える