What are the key differences between IEnumerable
Count()
and Length
?

- 32,488
- 9
- 84
- 95

- 3,968
- 6
- 40
- 48
3 Answers
By calling Count on IEnumerable<T>
I'm assuming you're referring to the extension method Count
on System.Linq.Enumerable
. Length
is not a method on IEnumerable<T>
but rather a property on array types in .NET, such as int[]
.
The difference is performance. TheLength
property is guaranteed to be a O(1) operation. The complexity of the Count
extension method differs based on runtime type of the object. It will attempt to cast to several types which support O(1) length lookup like ICollection<T>
via a Count
property. If none are available then it will enumerate all items and count them which has a complexity of O(N).
For example
int[] list = CreateSomeList();
Console.WriteLine(list.Length); // O(1)
IEnumerable<int> e1 = list;
Console.WriteLine(e1.Count()); // O(1)
IEnumerable<int> e2 = list.Where(x => x <> 42);
Console.WriteLine(e2.Count()); // O(N)
The value e2
is implemented as a C# iterator which does not support O(1) counting and hence the method Count
must enumerate the entire collection to determine how long it is.

- 30,738
- 21
- 105
- 131

- 733,204
- 149
- 1,241
- 1,454
-
8`List
` doesn't have a Length property - it has a Count property. Arrays have a `Length` though. `Count` is specified in `ICollection` and `ICollection – Jon Skeet Mar 26 '10 at 07:15` (which `IList ` extends). -
@JonSkeet and @Jared - In the context of parsing a short `string[]` array with say 5-10 elements... would you suggest `Array.Length` for performance then? – one.beat.consumer Apr 18 '12 at 19:20
-
1@one.beat.consumer: It would still be O(1) with `Count()` as the array will implement `ICollection
` - but it's less efficient than using `Length` directly. If you already know it's an array, I'd use `Length` *not* for efficiency, but because I'd view it as more idiomatic. Likewise I'd use the `Count` property for anything which had a compile-time type of `ICollection – Jon Skeet Apr 18 '12 at 19:25`. I'd call `Count()` when the *compile-time expression* is of type `IEnumerable `, even if I know it's really an array behind the scenes. -
@JonSkeet: Thanks. My (dumb) assumption was that `System.Array` was a much more basic class (similar to `object`); but after checking MSDN I see it implements several 'collection-related' interfaces. I'm a web programmer so "Count" made more semantic sense (like `header` vs. `div` in HTML) at first, but I understand your point since it is explicitly a `string[]` at compile-time `Length` makes more sense. – one.beat.consumer Apr 18 '12 at 19:49
-
Hi JaredPar, can you please explain whether complexity for list will still be O(1) if within some loop I will be changing this list? E.g. `while(list.Count() > 0)` some logics with add/remove actions. – Johnny_D Apr 30 '14 at 10:57
A little addition to Jon Skeet's comment.
Here is the source code of the Count()
extension method:
.NET 3:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
.NET 4:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
ICollection is3 = source as ICollection;
if (is3 != null)
{
return is3.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}

- 30,738
- 21
- 105
- 131

- 8,649
- 1
- 39
- 52
-
9Note that in .NET 4 there's another block to check for the non-generic `ICollection` type too. (As that also has a `Count` property.) – Jon Skeet Mar 26 '10 at 07:37
-
Does anyone know what to `use` to get the `Error` class that this method uses? I can't seem to find it anywhere on MSDN, except for the JScript documentation. – Moshe Katz Jun 10 '12 at 20:50
Length is a fixed property, e.g. of a single dimensional array or string. So there's never a count operation necessary (multi-dimensional arrays have a size of all dimensions multiplied). O(1) operation here means that retrieval time is always the same, no matter how many elements there are. A linear search would (opposed to this) be O(n).
The Count property on ICollections (List and List<T>, for example) can change, so it has either to be updated on Add/Remove operations, or when Count is requested after the Collection has changed. Depends on the implementation of the object.
The Count() method of LINQ basically iterates every time it is called (except when the object is an ICollection type, then the ICollection.Count property is requested).
Note that IEnumerables are often not already defined object collections (like lists, arrays, hash tables, etc.), but link to background operations, which generate results whenever they are requested (called deferred execution).
Typically, you have an SQL-like LINQ statement like this (the typical application of deferred execution):
IEnumerable<Person> deptLeaders =
from p in persons
join d in departments
on p.ID equals d.LeaderID
orderby p.LastName, p.FirstName
select p;
Then, there's code like this:
if (deptLeaders.Count() > 0)
{
ReportNumberOfDeptLeaders(deptLeaders.Count());
if (deptLeaders.Count() > 20)
WarnTooManyDepartmentLeaders(deptLeaders.Count());
}
So, when a warning for too many Department Leaders is issued, .NET goes four times through the persons, checks them against the department leaders, sorts them by name and then counts the result objects.
And this is only when persons and departments are preset value collections, not queries themselves.

- 30,738
- 21
- 105
- 131

- 1,114
- 1
- 13
- 28
-
-
2@sfjedi: I think it's not the same. Any() stops when an item has been found, while Count() iterates through all. So when having an IEnumerable, possible for deferred execution, Any() should be preferred for empty check. – Erik Hart Feb 09 '12 at 16:15
-
4Wouldn't `.Any()` be more efficient than `.Count() > 0` then? BTW, Resharper always complains about `.Count() > 0`. This is why I bring it up with confidence. – jedmao Feb 09 '12 at 17:47
-