GetEnumerator
Some .NET collection types offer the GetEnumerator
method. This method returns an Enumerator object that can be used to loop through the collection.
Complete knowledge of the actual collection type is not needed. We can use GetEnumerator
before a while
-loop, and call MoveNext
on each iteration.
This program shows how the GetEnumerator
method on the List
type works. On a List
of ints, GetEnumerator
returns a List
(int
) Enumerator object.
IEnumerator
(int
). We can then write methods that receive IEnumerator
(int
).GetEnumerator
, it becomes possible to write methods that act on the IEnumerator
interface
.LinkedList
returns LinkedList
(int
) Enumerator—a LinkedList
could also be passed to the Write method.using System; using System.Collections.Generic; class Program { static void Main() { // Create list of ints. List<int> list = new List<int>(); list.Add(1); list.Add(5); list.Add(9); // Call GetEnumerator on List. List<int>.Enumerator e = list.GetEnumerator(); Write(e); } static void Write(IEnumerator<int> e) { // Use the IEnumerator object. while (e.MoveNext()) { int value = e.Current; Console.WriteLine(value); } } }1 5 9
GetEnumerator
benchmarkWe can write methods that work on IEnumerator
, but is this efficient in .NET 7 in 2022? This benchmark tests GetEnumerator
performance.
MoveNext
on an IEnumerator
interface
to sum up a List
of integers.foreach
on a List
of integers directly and sum up all the values. The result is the same as version 1.foreach
over enumerators.using System; using System.Collections.Generic; using System.Diagnostics; class Program { static int CountMoveNext(IEnumerator<int> e) { int count = 0; while (e.MoveNext()) { int value = e.Current; count += value; } return count; } static int CountForeach(List<int> e) { int count = 0; foreach (int value in e) { count += value; } return count; } const int _max = 1000000; static void Main() { List<int> list = new List<int>(); list.Add(1); list.Add(5); list.Add(9); List<int>.Enumerator e = list.GetEnumerator(); var s1 = Stopwatch.StartNew(); // Version 1: use MoveNext. for (int i = 0; i < _max; i++) { var result = CountMoveNext(e); } s1.Stop(); var s2 = Stopwatch.StartNew(); // Version 2: use foreach. for (int i = 0; i < _max; i++) { var result = CountForeach(list); } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } }26.71 ns CountMoveNext 14.79 ns CountForeach
GetEnumerator
is an instance method provided on many collection types. A unified method can be used to loop over the Enumerator returned by all these collections.