Utilisation d'itérateurs (Guide de programmation C#)

La façon la plus courante de créer un itérateur est d'implémenter la méthode GetEnumerator sur l'interface IEnumerable, par exemple :

public System.Collections.IEnumerator GetEnumerator()
{
    for (int i = 0; i < 10; i++)
    {
        yield return i;
    }
}

La présence de la méthode GetEnumerator fait du type un type énumérable et autorise l'utilisation de l'instruction foreach. Si la méthode précitée faisait partie d'une définition de classe pour ListClass, il serait possible d'utiliser foreach sur la classe comme suit :

static void Main()
{
    ListClass listClass1 = new ListClass();

    foreach (int i in listClass1)
    {
        System.Console.Write(i + " ");
    }
    // Output: 0 1 2 3 4 5 6 7 8 9
}

L'instruction foreach appelle ListClass.GetEnumerator() et utilise l'énumérateur retourné pour itérer au sein des valeurs. Pour obtenir un exemple de création d'un itérateur générique qui retourne une interface IEnumerator<T>, consultez Comment : créer un bloc itérateur pour une liste générique (Guide de programmation C#).

Il est également possible d'utiliser des itérateurs nommés pour prendre en charge différentes façons d'itérer au sein de la même collection de données. Par exemple, vous pourriez fournir un itérateur qui retourne des éléments en ordre croissant, et un autre qui retourne des éléments en ordre décroissant. Un itérateur peut également avoir des paramètres permettant aux clients de contrôler tout ou une partie du comportement d'itération. L'itérateur suivant implémente l'interface IEnumerable à l'aide de l'itérateur nommé SampleIterator :

// Implementing the enumerable pattern
public System.Collections.IEnumerable SampleIterator(int start, int end)
{
    for (int i = start; i <= end; i++)
    {
        yield return i;
    }
}

L'itérateur nommé est appelé comme ceci :

ListClass test = new ListClass();

foreach (int n in test.SampleIterator(1, 10))
{
    System.Console.Write(n + " ");
}
// Output: 1 2 3 4 5 6 7 8 9 10

Vous pouvez utiliser plusieurs instructions yield dans l'itérateur comme dans l'exemple suivant :

public System.Collections.IEnumerator GetEnumerator()
{
    yield return "With an iterator, ";
    yield return "more than one ";
    yield return "value can be returned";
    yield return ".";
}

Vous pouvez ensuite imprimer les résultats à l'aide de l'instruction foreach suivante :

foreach (string element in new TestClass())
{
    System.Console.Write(element);
}
// Output: With an iterator, more than one value can be returned.

Cet exemple affiche le texte suivant :

With an iterator, more than one value can be returned.

À chaque itération successive de la boucle foreach (ou l'appel direct à IEnumerator.MoveNext), le corps du code de l'itérateur suivant reprend après l'instruction yield précédente et passe à la suivante jusqu'à la fin du corps d'itérateur, ou jusqu'à ce qu'une instruction yield break soit rencontrée.

Les itérateurs ne prennent pas en charge la méthode IEnumerator.Reset. Pour effectuer de nouveau à une itération depuis le début, vous devez vous procurer un nouvel itérateur.

Exemple

Le code suivant contient tous les exemples de cette rubrique.

namespace UsingIterators
{
    class Program
    {
        static void Main()
        {
            // Using a simple iterator.
            ListClass listClass1 = new ListClass();

            foreach (int i in listClass1)
            {
                System.Console.Write(i + " ");
            }
            // Output: 0 1 2 3 4 5 6 7 8 9
            System.Console.WriteLine();


            // Using a named iterator.
            ListClass test = new ListClass();

            foreach (int n in test.SampleIterator(1, 10))
            {
                System.Console.Write(n + " ");
            }
            // Output: 1 2 3 4 5 6 7 8 9 10
            System.Console.WriteLine();


            // Using multiple yield statements.
            foreach (string element in new TestClass())
            {
                System.Console.Write(element);
            }
            // Output: With an iterator, more than one value can be returned.
            System.Console.WriteLine();

        }
    }

    class ListClass : System.Collections.IEnumerable
    {

        public System.Collections.IEnumerator GetEnumerator()
        {
            for (int i = 0; i < 10; i++)
            {
                yield return i;
            }
        }

        // Implementing the enumerable pattern
        public System.Collections.IEnumerable SampleIterator(int start, int end)
        {
            for (int i = start; i <= end; i++)
            {
                yield return i;
            }
        }
    }

    class TestClass : System.Collections.IEnumerable
    {
        public System.Collections.IEnumerator GetEnumerator()
        {
            yield return "With an iterator, ";
            yield return "more than one ";
            yield return "value can be returned";
            yield return ".";
        }
    }
}

Voir aussi

Tâches

Comment : créer un bloc itérateur pour une liste d'entiers (Guide de programmation C#)

Comment : créer un bloc itérateur pour une liste générique (Guide de programmation C#)

Référence

yield (Référence C#)

Utilisation de foreach avec des tableaux (Guide de programmation C#)

foreach, in (référence C#)

Concepts

Guide de programmation C#