Count the items from a IEnumerable<T> without iterating?
IEnumerable
doesn't support this. This is by design. IEnumerable
uses lazy evaluation to get the elements you ask for just before you need them.
If you want to know the number of items without iterating over them you can use ICollection<T>
, it has a Count
property.
The System.Linq.Enumerable.Count
extension method on IEnumerable<T>
has the following implementation:
ICollection<T> c = source as ICollection<TSource>;
if (c != null)
return c.Count;
int result = 0;
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
result++;
}
return result;
So it tries to cast to ICollection<T>
, which has a Count
property, and uses that if possible. Otherwise it iterates.
So your best bet is to use the Count()
extension method on your IEnumerable<T>
object, as you will get the best performance possible that way.
Just adding extra some info:
The Count()
extension doesn't always iterate. Consider Linq to Sql, where the count goes to the database, but instead of bringing back all the rows, it issues the Sql Count()
command and returns that result instead.
Additionally, the compiler (or runtime) is smart enough that it will call the objects Count()
method if it has one. So it's not as other responders say, being completely ignorant and always iterating in order to count elements.
In many cases where the programmer is just checking if( enumerable.Count != 0 )
using the Any()
extension method, as in if( enumerable.Any() )
is far more efficient with linq's lazy evaluation as it can short-circuit once it can determine there are any elements. It's also more readable