Enumerate an IDictionary.Keys collection which is an ICollection<T>

.net, c#, enumeration

Solution

`foreach` simply needs `IEnumerable`; whereas `for(a,b,c)` (in your case) requires an indexer property.

When you call `foreach` on an object that implements `IEnumerable`, under the hood it calls `GetEnumerator()`, which returns an IEnumerator object. That object implements a few members like `MoveNext()` and `Current`. Each iteration of the `foreach` is actually calling `MoveNext()`, which returns `true` if the enumerator can move forward, and false if it can't (reached the end).

The key here is that an object which implements `IEnumerable` does not know how many items it has, the index of the item it's on, etc. All it knows is that it can move forward to the next item, return that as the current item, until it runs out of items.

A `for(a,b,c)` loop, on the other hand, will essentially loop forever - i.e. it is not constrained by the collection you might happen to be iterating over (although in practice it usually is). At the most basic level, it executes `C` once each time, and checking if `B` is true. If `B` is true, it will loop again. If it's false, it will stop. Each time it loops, inside the loop you are probably calling `object[number]`, which if your object does not have such a property, will of course fail.

The key here is that an object with an indexer supports random access - that means you can, at any point, call `[arbitrary index]` and grab that one. Contrast this with `IEnumerable`, which again can only access the current item.

Problem

I hope i don't get slammed for asking something so basic. I could Google for the answer, but I want to hear something that's not from a textbook. I'm writing a unit test to verify that my `IDictionary` Keys are sequential. Since the `Keys` property is an `ICollection<T>`, I want to enumerate over the collection and print the Key values to the console. When attempting to print the Key values using a simple `for` loop: ``` for (int i = 0; i < unPivotedData.Count; i++) { Console.WriteLine(unPivotedData.Keys[i]); } ``` I received the following compile error: ``` Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.ICollection<int>' ``` However, when I used the `foreach` loop: ``` foreach(int key in unPivotedData.Keys) { Console.WriteLine(key); } ``` Everything worked just fine. I understand what an indexer does and how it's implemented, but how does the `foreach` work? I don't understand how the `foreach` can work yet the `for` results in a compiler error. Am I missing a fundamental of Enumeration here? Cheers! EDIT: Furthermore, is there a performance difference between the two? I know I cannot use `for` with an IDictionary but if I'm using an IList, I can. Does the `for` move quicker than the `foreach` or is the performance gain negligible

Original source