web-dev-qa-db-fra.com

Comment fonctionnent les boucles foreach en C #?

Quels types de classes peuvent utiliser les boucles foreach?

83
user48616

En fait, strictement parlant, tout ce dont vous avez besoin d’utiliser foreach est une méthode publique GetEnumerator() qui retourne quelque chose avec une méthode bool MoveNext() et un ? Current {get;} Propriété. Cependant, le plus commun sens est "quelque chose qui implémente IEnumerable/IEnumerable<T>, Retournant un IEnumerator/IEnumerator<T>.

Cela implique implicitement tout ce qui implémente ICollection/ICollection<T>, Comme par exemple Collection<T>, List<T>, Des tableaux (T[]), etc. Ainsi, toute "collection de données" standard supportera généralement foreach.

Pour prouver le premier point, voici ce qui fonctionne:

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 marche?

Une boucle foreach telle que foreach(int i in obj) {...} équivaut un peu à:

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, si l’énumérateur (tmp) prend en charge IDisposable, il est également utilisé (comme using).

Notez la différence dans l'emplacement de la déclaration "int i" à l'intérieur de (C # 5.0) vs. en dehors (jusqu'à C # 4.0) de la boucle. C'est important si vous utilisez i dans une méthode anonyme/lambda à l'intérieur de votre bloc de code. Mais c’est une autre histoire ;-p

158
Marc Gravell

De MSDN :

L'instruction foreach répète un groupe d'instructions incorporées pour chaque élément d'un d'un tableau ou d'une collection d'objets . L'instruction foreach est utilisée pour parcourir la collection afin d'obtenir les informations souhaitées, mais ne doit pas être utilisée pour modifier le contenu de la collection afin d'éviter des effets secondaires imprévisibles. (c'est moi qui souligne)

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

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

Vous pouvez aussi l'utiliser pour parcourir un List<T> collection, comme ceci:

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

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

Selon le post du blog Notation de canard, la saisie au clavier est utilisée.

4
tuinstoel

Voici la documentation: Article principalAvec des tableauxAvec des objets de collection

Il est important de noter que "Le type de l'élément de collection doit être convertible en type d'identificateur". Cela ne peut parfois pas être vérifié lors de la compilation et peut générer une exception d'exécution si le type d'instance n'est pas assignable au type de référence.

Cela générera une exception d'exécution s'il y a un non-Apple dans le panier de fruits, tel qu'une orange.

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

Ceci filtre en toute sécurité la liste aux seules pommes utilisant Enumerable.OfType

foreach(Apple a in fruitBasket.OfType<Apple>() )
2
Amy B