Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is difference between System.Linq.Enumerable.WhereListIterator & System.Linq.Enumerable.WhereSelectListIterator?

Tags:

c#

linq

func

where

What is difference between System.Linq.Enumerable.WhereListIterator & System.Linq.Enumerable.WhereSelectListIterator?

One difference I hav noticed is Type WhereListIterator reflects changes on collection object but WhereSelectListIterator does not

I will make it more clear for eg.

I hav a scenario where I fetch my Domain Object from Repository

var buckets = testRepository.GetBuckets(testIds);

Then I select certain buckets from the above collection inside a loop

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

Then I change a single property of all the Bucket Objects inside the method of LooserTrafficDisributor object.

ITrafficDistributor distributor = new LooserTrafficDisributor(bucketsForTest);

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

Constructor of LooserTrafficDisributor

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

The distribute method inside LooserTrafficDistributor looks like this

 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
 }

After this I can see the reflected changes inside the IEnumerable updatedBuckets collection.

But if I do this i.e. instead of fetching Bucket collection from repository do a select & then Update all the Bucket objects in similar manner as follows

 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());

I can't get the changes reflected inside the IEnumerable updatedBuckets collection. Infact I debugged inside the DistributeTraffic methods even there the changes were not reflected after each loop round.

like image 341
Vipresh Avatar asked Oct 10 '22 16:10

Vipresh


1 Answers

.Where() makes an IEnumerable of your items containing all elements which fullfil the where criteria. If you run a .Select() on that result set, you will get a IEnumerable of new elements you've created in the select-statement. So changes to the original elements will not reflect on the new elements.

In your example you create for every Bucket in the original list fullfilling your where criteria a new Bucket object, copying the content from the original bucket to the new Bucket.

like image 142
Fischermaen Avatar answered Oct 12 '22 14:10

Fischermaen