Codecademy Logo

C# Iterators

C# Advanced Iterators

In C#, advanced iterator patterns such as nested iterators, infinite sequences, and the combination of yield return with regular return statements enhance code flexibility and efficiency. These patterns enable the creation of complex data enumerations and allow developers to handle streams of data dynamically.

C# Iterators

Iterators in C# allow you to iterate over sequences of data. They provide an efficient way to manage collection traversal and can enhance code readability and performance.

using System;
using System.Collections;
public class CustomIterator : IEnumerable
{
private int[] numbers = { 1, 2, 3, 4, 5 };
public IEnumerator GetEnumerator() {
for (int i = 0; i < numbers.Length; i++) {
yield return numbers[i];
}
}
}
public class Program {
public static void Main() {
var iterator = new CustomIterator();
foreach(var number in iterator) {
Console.WriteLine(number);
}
}
}

C# Iterator Methods

Understanding iterator methods is integral to managing collections in C#. An iterator method allows objects to be retrieved one at a time via yield return, providing flexibility in both synchronous (IEnumerable<T>) and asynchronous (IAsyncEnumerable<T>) operations. This approach enhances performance by only generating items as needed.

using System.Collections.Generic;
using System.Threading.Tasks;
public class IteratorExample
{
// Synchronous iterator
public IEnumerable<int> GetNumbers()
{
for (int i = 0; i < 5; i++)
{
yield return i;
}
}
// Asynchronous iterator
public async IAsyncEnumerable<int> GetNumbersAsync()
{
for (int i = 0; i < 5; i++)
{
await Task.Delay(100);
yield return i;
}
}
}

C# Custom Iterators

In C#, developers can create custom iterators by implementing the IEnumerable<T> and IEnumerator<T> interfaces manually. This allows for customized iteration logic, putting you in control of how elements in a collection are accessed.

// Example: Custom Iterator Implementation in C#
using System;
using System.Collections;
using System.Collections.Generic;
public class CustomCollection<T> : IEnumerable<T>
{
private readonly List<T> _items = new List<T>();
public void Add(T item) => _items.Add(item);
public IEnumerator<T> GetEnumerator() => new CustomEnumerator(_items);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private class CustomEnumerator : IEnumerator<T>
{
private readonly List<T> _items;
private int _position = -1;
public CustomEnumerator(List<T> items) => _items = items;
public T Current => _items[_position];
object IEnumerator.Current => Current;
public bool MoveNext() => ++_position < _items.Count;
public void Reset() => _position = -1;
public void Dispose() { /* not needed */ }
}
}
// Usage
var collection = new CustomCollection<int>();
collection.Add(1);
collection.Add(2);
collection.Add(3);
foreach (var item in collection)
{
Console.WriteLine(item);
}

Lazy Evaluation C#

In C#, lazy evaluation in iterators delays the execution of a function until its result is needed. This optimizes performance and enhances memory efficiency by computing items only when required, avoiding unnecessary processing.

using System;
using System.Collections.Generic;
class Program
{
static IEnumerable<int> LazyNumbers()
{
Console.WriteLine("Generating numbers");
yield return 1;
yield return 2;
yield return 3;
}
static void Main()
{
IEnumerable<int> numbers = LazyNumbers();
Console.WriteLine("Number sequence created.");
foreach (var num in numbers)
{
Console.WriteLine(num);
}
}
}
/* Output:
Number sequence created.
Generating numbers
1
2
3
*/

C# Yield Keyword

The yield keyword in C# is used within an iterator block to define a sequence’s elements and control iteration. It simplifies code by allowing state retention between calls without requiring a temporary collection. This enhances memory efficiency and readability.

using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
foreach (int number in GenerateNumbers())
{
Console.WriteLine(number);
}
}
static IEnumerable<int> GenerateNumbers()
{
for (int i = 1; i <= 3; i++)
{
yield return i;
}
}
}

Learn more on Codecademy