86 votes

Comment fonctionnent les boucles foreach en C #?

Quels types de classes peuvent utiliser des boucles foreach ?

167voto

Marc Gravell Points 482669

En fait, strictement parlant, tout ce que vous devez utiliser foreach public GetEnumerator() méthode qui renvoie à quelque chose avec un bool MoveNext() méthode et un ? Current {get;} de la propriété. Cependant, la plupart des communes de la signification de ce "quelque chose qui implémente IEnumerable/IEnumerable<T>, au retour d'une IEnumerator/IEnumerator<T>.

En conséquence, cela comprend tout ce qui implémente ICollection/ICollection<T>, comme quelque chose comme Collection<T>, List<T>, tableaux (T[]), etc. De sorte que toute norme "collecte des données" généralement en faveur des foreach.

Pour la preuve du premier point, le suivant fonctionne très bien:

using System;
class Foo {
    public int Current { get; private set; }
    private int step;
    public bool MoveNext() {
        if (step >= 5) return false;
        Current = step++;
        return true;
    }
}
class Bar {
    public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
    static void Main() {
        Bar bar = new Bar();
        foreach (int item in bar) {
            Console.WriteLine(item);
        }
    }
}

Comment ça fonctionne?

Une boucle foreach, comme foreach(int i in obj) {...} plutôt équivaut à:

var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
    int i; // C# 5.0
    i = tmp.Current;
    {...} // your code
}

Cependant, il y a des variations. Par exemple, l'agent recenseur (tmp) soutient IDisposable, il est utilisé trop (similaire à l' using).

Notez la différence dans la mise en place de la déclaration,"int i" à l'intérieur de (C# 5.0) par rapport à l'extérieur (C# 4.0) de la boucle. Il est important si vous utilisez i dans une méthode anonyme/lambda à l'intérieur de votre code-block. Mais c'est une autre histoire ;-p

7voto

George Stocker Points 31258

À partir de MSDN:

L' foreach déclaration répète un groupe de intégrée de déclarations pour chaque élément d'un tableau ou d'un objet la collecte. L' foreach déclaration est utilisé pour parcourir la collection pour obtenir l'information désirée, mais ne doit pas être utilisé pour modifier la contenu de la collection, pour éviter imprévisible des effets secondaires. (l'emphase est mienne)

Donc, si vous avez un tableau, vous pouvez utiliser l'instruction foreach pour parcourir le tableau, comme ceci:

 int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
    foreach (int i in fibarray)
    {
        System.Console.WriteLine(i);
    }

Vous pouvez également l'utiliser pour effectuer une itération dans un List<T> de la collection, comme suit:

List<string> list = new List<string>();

foreach (string item in list)
{
    Console.WriteLine(item);
}

4voto

tuinstoel Points 6329

Selon le blog Duck Notation , la dactylographie est utilisée.

2voto

David B Points 53123

Voici les docs: article Principal Avec les Tableaux Avec les Objets de Collection

Il est important de noter que "Le type de la collection de l'élément doit être convertie dans le type d'identificateur". Parfois, cela ne peut pas être vérifié au moment de la compilation, et peut générer une exception d'exécution si le type d'instance n'est pas cessible au type de référence.

Cela va générer une exception d'exécution si il y a un non-Pomme dans la corbeille de fruits, comme une orange.

List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)

Ce en toute sécurité les filtres de la liste seulement les Pommes à l'aide de Énumérable.OfType

foreach(Apple a in fruitBasket.OfType<Apple>() )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X