Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Something better than .ToArray() to force enumeration of LINQ output

Tags:

c#

linq

.net-3.5

I'm working with LINQ to objects and have a function where in some cases I need to modify the underlying collection before calling Aggregate(...) and then return it to its original state before the funciton returns the results of Aggregate(...). My current code looks something like this:

bool collectionModified = false;
if(collectionNeedsModification)
{
    modifyCollection();
    collectionModified = true;
}

var aggregationResult = from a in
                            (from b in collection
                             where b.SatisfysCondition)
                             .Aggregate(aggregationFunction)
                        select a.NeededValue;

if(collectionModified)
    modifyCollection();

return aggregationResult;

However, as written, if I modify the collection, I will get the wrong result because I'm putting the collection back in its original state before aggregationResult is enumerated and LINQ results are lazy-evaluated. My current solution is to use .ToArray() on my LINQ query like this:

var aggregationResult = (from a in
                            (from b in collection
                             where b.SatisfysCondition)
                             .Aggregate(aggregationFunction)
                         select a.NeededValue).ToArray();

The size of the resulting array will always be small (< 100 items) so memory / processing time is not a concern. Is this the best way to handle my problem, or is there a better way to force the evaluation of a LINQ query?

like image 758
Jon Norton Avatar asked Nov 24 '08 13:11

Jon Norton


People also ask

What is faster ToList or ToArray?

ToArray might do an additional allocation and copy operation such that the buffer will be sized exactly to the number of elements. In order to confirm this the following benchmark is used. The results confirm that ToList is in most cases 10% - 15% faster.

What is ToList in Linq?

LINQ ToList() Method In LINQ, the ToList operator takes the element from the given source, and it returns a new List. So, in this case, input would be converted to type List.

What is ToList C#?

This extension method converts collections (IEnumerables) to List instances. It is fast and easy-to-remember. It returns a List instance with the appropriate elements.


1 Answers

Just to check I understand you - you basically want to iterate through all of the results, just to force any side effects to take place?

Side effects are generally a bad idea precisely because things are harder to understand with this kind of logic. Having said that, the easiest way to do it and force full evaluation is probably to just iterate through it:

foreach (var result in aggregationResult)
{
    // Deliberately empty; simply forcing evaluation of the sequence.
}

Alternatively you could use LastOrDefault() to avoid all the copying involved in ToArray(). Count() will be okay so long as the result doesn't implement IList<T> (which involves a short-cut).

like image 173
Jon Skeet Avatar answered Oct 08 '22 03:10

Jon Skeet