11

I was writing some code, and went to get the length of an IEnumerable. When I wrote myEnumerable.Count(), to my surprise, it did not compile. After reading Difference between IEnumerable Count() and Length, I realized that it was actually Linq that was giving me the extension method.

Using .Length does not compile for me either. I am on an older version of C#, so perhaps that is why.

What is the best practice for getting the length of an IEnumerable? Should I use Linq's Count() method? Or is there a better approach. Does .Length become available on a later version of C#?

Or if I need the count, is an IEnumerable the wrong tool for the job? Should I be using ICollection instead? Count the items from a IEnumerable<T> without iterating? says that ICollection is a solution, but is it the right solution if you want an IEnumerable with a count?

Obligatory code snippet:

var myEnumerable = IEnumerable<Foo>();

int count1 = myEnumerable.Length; //Does not compile

int count2 = myEnumerable.Count(); //Requires Linq namespace

int count3 = 0; //I hope not
for(var enumeration in myEnumerable)
{
    count3++;
}
Christos
  • 53,228
  • 8
  • 76
  • 108
Evorlor
  • 7,263
  • 17
  • 70
  • 141
  • 2
    It looks like you might want to be using [`IReadOnlyCollection`](https://msdn.microsoft.com/en-us/library/hh881542(v=vs.110).aspx), which gives you a combination of an `IEnumerable` with a `.Count` property. – Matthew Watson May 21 '18 at 11:59
  • 2
    `IEnumerable` defines iterator that can be used to iterate over a collection. It doesn't know how big the collection is. If you need to know the size of the collection then `IEnumerable` is not sufficient and you need to find other structure that will have the feature of tracking number of elements, such as `IList` – FCin May 21 '18 at 12:05
  • 2
    If you own code which provides you with that `IEnumerable` (say that's return type of your own method) - you should consider changing it to return more appropriate type. – Evk May 21 '18 at 12:34

1 Answers1

9

If you need to read the number of items in an IEnumerable<T> you have to call the extension method Count, which in general (look at Matthew comment) would internally iterate through the elements of the sequence and it will return you the number of items in the sequence. There isn't any other more immediate way.

If you know that your sequence is an array, you could cast it and read the number of items using the Length property.

No, in later versions there isn't any such method.

For implementation details of Count method, please have a look at here.

Christos
  • 53,228
  • 8
  • 76
  • 108
  • 7
    Note that `Linq.Count()` is clever enough to recognise arrays and lists that implement `ICollection` to avoid iterating and just casts and return `Count`, an O(1) rather than an O(N) operation. [See the source code.](https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,41ef9e39e54d0d0b) – Matthew Watson May 21 '18 at 12:02
  • 1
    @MatthewWatson thanks for pointing this out. – Christos May 21 '18 at 12:05
  • 2
    this is all well and right, but it creates so much clutter given that the [possible duplicate](https://stackoverflow.com/a/853478/1132334) has answers likewise covering these options and the implementation details. – Cee McSharpface May 21 '18 at 12:09