Quels types de classes peuvent utiliser les boucles foreach
?
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
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'instructionforeach
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);
}
Selon le post du blog Notation de canard, la saisie au clavier est utilisée.
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>() )