5

System.Linq.Enumerable.WhereListIterator 和 System.Linq.Enumerable.WhereSelectListIterator 有什么区别?

我注意到的一个区别是类型 WhereListIterator 反映了集合对象的变化,但 WhereSelectListIterator 没有

我会更清楚地说明例如。

我有一个场景,我从存储库中获取我的域对象

var buckets = testRepository.GetBuckets(testIds);

然后我从循环内的上述集合中选择某些桶

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

然后我在 LooserTrafficDisributor 对象的方法中更改所有 Bucket 对象的单个属性。

ITrafficDistributor distributor = new LooserTrafficDisributor(bucketsForTest);

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

LooserTrafficDistributor 的构造函数

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

LooserTrafficDistributor 内部的分发方法如下所示

 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 集合中反映的更改。

但是,如果我这样做,即不是从存储库中获取 Bucket 集合,而是选择然后以类似的方式更新所有 Bucket 对象,如下所示

 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()使您的项目的 IEnumerable 包含满足 where 条件的所有元素。如果您.Select()在该结果集上运行 a,您将获得您在 select 语句中创建的新元素的 IEnumerable。因此,对原始元素的更改不会反映在新元素上。

在您的示例中,您为原始列表中的每个 Bucket 创建了一个新的 Bucket 对象,将原始存储桶中的内容复制到新的 Bucket 对象中。

于 2011-10-25T11:20:48.173 回答