Question

Suppose I have this :

IEnumerable<MyObject> StructsTemp;

I wrote n queries on StructsTemp, so that it populates from the DB, and so on. Later, I execute them calling .ToList() :

IList<MyObject> StructsFinal = StructsTemp.ToList();
... some queries on StructsFinal ....
StructsTemp = StructsFinal;

What about if later I do this?

StructsTemp.Count()

Will it re-execute the n queries on StructsTemp? Will this re-execute StructsTemp.ToList()? Will this re-execute all queries on StructsFinal?

Was it helpful?

Solution

If you assign a reference of List<T> to the variable StructsTemp, the IEnumerable<T> actuallyis a List<T> and will use it's Count property instead of enumerating the underlying sequence.

var numbers = new []{ 1,2,3 };
IEnumerable<int>evenNumbers = numbers.Where(i=> i % 2 == 0);
// deferred, will enumerate the sequence to count the even numbers
int count = evenNumbers.Count();
evenNumbers = evenNumbers.ToList();
// not deferred, using the Count property of List<T>
count = evenNumbers.Count();

So the latter will always return the same value since it's persisted in a new collection. The former can return a different result on each iteration when the underlying collection has changed(f.e. numbers.Remove(2) causes evenNumbers.Count to be 0) .

Edit:

Here's a more meaningful demo of that behaviour: http://ideone.com/91Yrh

OTHER TIPS

ToList() will force the evaluatation of StructsTemp, whatever that is, but it has no effect on the subsequent Linq.

... some queries on StructsFinal .... may or may not be lazy evaluated, lets assume it\they are.

the Count() extension is not lazy so would force the execution of ... some queries on StructsFinal ....,

As an aside, if the result of ... some queries on StructsFinal .... implements ICollection<T>, like IList<T> does, then the Count() extension will just access the Count property of the result.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top