IEnumerable is pretty simple:
[ComVisibleAttribute(True)]
[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
And for completeness, IEnumerator
[ComVisibleAttribute(true)]
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
Object Current {get;}
bool MoveNext();
void Reset();
}
But more often what you're really seeing in code samples is IEnumerable<T>
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
IEnumerator GetEnumerator(); //inherited from IEnumerable
}
And again for completeness, IEnumerator<T> (with IDisposable):
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
void Dispose(); //inherited from IDsiposable
Object Current {get;} //inherited from IEnumerator
T Current {get;}
bool MoveNext(); //inherited from IEnumerator
void Reset(); //inherited from IEnumerator
}
[ComVisibleAttribute(true)]
public interface IDisposable
{
void Dispose();
}
That's really all there is to it. There is no direct implementation code for any of this that's specific to IEnumerable or the related code show here. Rather, types like arrays or List<T> will inherit from IEnumerable and implement the required methods. Everything else beyond that is done via extension methods.
What makes it all even more powerful are these items:
- C#'s
foreach
keyword supports looping over anything that has a GetEnumerator()
method that returns an IEnumerator, and therefore you can use any type that implements IEnumerable with a foreach loop.
- The linq query comprehension syntax works in a similar way, such that you can use most any IEnumerable with linq to objects.
- The
yield
keyword allows you to create something called iterator blocks. Iterator blocks have some neat properties (like lazy evaluation) and allow you easily create your own IEnumerable types without having to go to all the trouble of defining a new class first.
Finally, it's worth pointing out here that IDisposable is another interface worth further study, as it is used quite a bit in the framework and has direct language support similar to IEnumerable's foreach
with the using
keyword.