Quels types de classes peuvent utiliser des boucles foreach
?
Réponses
Trop de publicités?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
À 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);
}
Selon le blog Duck Notation , la dactylographie est utilisée.
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>() )