Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>foreach</code> <em>uses</em> the interfaces in many cases. You need the interfaces if you want to <em>implement</em> a sequence which <code>foreach</code> can then use. (Iterator blocks usually make this implementation task very simple though.)</p> <p>However, just <em>occasionally</em> it can be useful to use the iterators directly. A good example is when trying to "pair up" two different sequences. For example, suppose you receive two sequences - one of names, one of ages, and you want to print the two together. You might write:</p> <pre><code>static void PrintNamesAndAges(IEnumerable&lt;string&gt; names, IEnumerable&lt;int&gt; ages) { using (IEnumerator&lt;int&gt; ageIterator = ages.GetEnumerator()) { foreach (string name in names) { if (!ageIterator.MoveNext()) { throw new ArgumentException("Not enough ages"); } Console.WriteLine("{0} is {1} years old", name, ageIterator.Current); } if (ageIterator.MoveNext()) { throw new ArgumentException("Not enough names"); } } } </code></pre> <p>Likewise it can be useful to use the iterator if you want to treat (say) the first item differently to the rest:</p> <pre><code>public T Max&lt;T&gt;(IEnumerable&lt;T&gt; items) { Comparer&lt;T&gt; comparer = Comparer&lt;T&gt;.Default; using (IEnumerator&lt;T&gt; iterator = items.GetEnumerator()) { if (!iterator.MoveNext()) { throw new InvalidOperationException("No elements"); } T currentMax = iterator.Current; // Now we've got an initial value, loop over the rest while (iterator.MoveNext()) { T candidate = iterator.Current; if (comparer.Compare(candidate, currentMax) &gt; 0) { currentMax = candidate; } } return currentMax; } } </code></pre> <hr> <p>Now, if you're interested in the difference between <code>IEnumerator&lt;T&gt;</code> and <code>IEnumerable&lt;T&gt;</code>, you might want to think of it in database terms: think of <code>IEnumerable&lt;T&gt;</code> as a table, and <code>IEnumerator&lt;T&gt;</code> as a cursor. You can ask a table to give you a new cursor, and you can have multiple cursors over the same table at the same time.</p> <p>It can take a while to really grok this difference, but just remembering that a list (or array, or whatever) doesn't have any concept of "where you are in the list" but an iterator over that list/array/whatever <em>does</em> have that bit of state is helpful.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload