-
Notifications
You must be signed in to change notification settings - Fork 1
Iterators
Note: these examples don't use the generic versions. Use the generic versions to prevent penalties incurred by auto-boxing.
public interface IEnumerable
{
IEnumerator GetEnumerator(); // Used by the foreach loop.
}
public interface IEnumerator
{
bool MoveNext(); // Advance the cursor position.
object Current() { get; } // Get the current item.
void Reset(); // Reset the cursor.
}
public class SomeClass : IEnumerable
{
// ...
// This is a special "iterator" method.
public IEnumerator GetEnumerator()
{
for (var i = 0; i < items.Length; ++i)
{
// The compiler automatically generates a nested IEnumerator that
// keeps track of execution, and returns items[i] for Current.
yield return items[i];
// You cannot call Reset on an instance of this generated IEnumerator,
// you'll have to get a new instance of it.
}
}
// This is a "named iterator" method.
public IEnumerator GetReverseEnumerator(string msg)
{
Console.WriteLine("Named iterators can receive parameters: " + msg);
for (var i = items.Length-1; i >= 0; --i)
{
yield return items[i];
}
}
}
You can use the iterators in a foreach
loop.
foreach (Item it in someClass) {}
foreach (Item it in someClass.GetReverseEnumerator()) {}
When you use the yield keyword in a statement, you indicate that the method, operator, or "get" accessor in which it appears is an iterator. Using yield to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator)
-
yield return
- return each element one at a time. -
yield break
- end iteration.
You consume an iterator by using a foreach statement or LINQ query.
Each iteration of the foreach loop calls the iterator. When a
yield return
statement is reached in the iterator method, the expression is
returned, and the current location in code is retained. Execution is
restarted from that location the next time that the iterator function is
called.
yield
is not a reserved word and has special meaning only when
it is used before a return
or break
keyword.
An iterator method cannot have any ref
or out
parameters.
An implicit conversion must exist from the expression type in the yield return
statement to the return type of the iterator.
- Abstract Classes
- Access Modifiers
- Anonymous Methods
- Anonymous Types
- Arrays
- Attributes
- Console I/O
- Constructors
- Const Fields
- Delegates
- Enums
- Exceptions
- Extension Methods
- File IO
- Generics
- Interfaces
- Iterators
- LINQ
- Main
- Null Operators
- Parameters
- Polymorphism
- Virtual Functions
- Reflection
- Serialization
- Strings
- Value Types
- "Base" Keyword
- "Is" and "As"
- "Sealed" Keyword
- nameof expression