Reputation: 4806
So I understand that the most common collections in C#
all implement the IEnumerable<T>
interface: List<T>
, T[]
and Dictionary<TKey,TVal>
all do this.
However, when you run a LINQ query such as:
myCol.Where(myBoolMethod);
You are returned data as an unknown type that implements IEnumerable<T>
.
Consequently, I'm wondering how this data is actually stored until you convert it into a more useful format through .ToList()
, .ToArray()
etc.
Does it remain in the type of the source? Does it get stored in a pseudo-array? Is it some sort of combination of the above?
Further to this, is there any reason why converting to one type of IEnumerable<T>
will ALWAYS be quicker than converting to a different one from - ie where myCol.Where(myBoolMethod).ToArray()
is always quicker than myCol.Where(myBoolMethod).ToList()
regardless of the data types involved?
Upvotes: 5
Views: 611
Reputation: 34199
When you do myCol.Where(myBoolMethod)
the data is actually not being enumerated. It is not stored in array or whatever else, you just get the enumerator which lets you enumerate this collection.
When you do .ToArray()
it actually uses enumerator to create a new array.
Upvotes: 0
Reputation: 156978
Does it remain in the type of the source? Does it get stored in a pseudo-array? Is it some sort of combination of the above?
Most LINQ extension methods will loop over the source every time you access the resulting IEnumerable<T>
(it's called deferred execution). The results are generally not stored in an intermediate source.
is there any reason why converting to one type of IEnumerable will ALWAYS be quicker than converting to a different one from
Yes, calling ToArray
or ToList
will execute the enumerable and materialize it. If you don't use the returned IEnumerable<T>
, it will not materialize it. The performance impact is about 0.
Upvotes: 3
Reputation: 1062
That's actually WhereEnumerableIterator
(if myCol is IEnumerable
).
http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,119
It contains just reference to initial myCol
and reference to Func<T, bool>
.
If mycol
is another type, it could be another, more optimized LINQ iterator.
Upvotes: 0
Reputation: 239704
It's not stored. It represents the ability to obtain the data at a later point in time, but the data itself is still lurking in the original collection(s) from which the linq query has been composed. (And any logic that exists to create new values from expressions)
This is why there are all kinds of admonitions against storing these results without using a ToXxx
method if there's any possibility that you'll actually cause the query to execute multiple times.
Upvotes: 5