Vous voudrez peut-être choisir une autre réponse acceptée, car celle que vous avez sélectionnée n'est pas vraiment représentative de la bonne réponse.
George Stocker
Réponses:
162
En fait, à proprement parler, tout ce dont vous avez besoin foreachest une GetEnumerator()méthode publique qui renvoie quelque chose avec une bool MoveNext()méthode et une ? Current {get;}propriété. Cependant, la signification la plus courante de ceci est "quelque chose qui implémente IEnumerable/ IEnumerable<T>, retournant un IEnumerator/ IEnumerator<T>.
Implicitement, cela inclut tout ce qui met en œuvre ICollection/ ICollection<T>, comme quelque chose comme Collection<T>, List<T>, les tableaux ( T[]), etc. Ainsi , toute « collecte de données » standard supportent en général foreach.
Pour preuve du premier point, ce qui suit fonctionne très bien:
using System;
classFoo {
publicint Current { get; privateset; }
privateint step;
publicboolMoveNext() {
if (step >= 5) returnfalse;
Current = step++;
returntrue;
}
}
classBar {
public Foo GetEnumerator() { returnnew Foo(); }
}
staticclassProgram {
staticvoidMain() {
Bar bar = new Bar();
foreach (int item in bar) {
Console.WriteLine(item);
}
}
}
Comment ça marche?
Une boucle foreach comme foreach(int i in obj) {...}un peu équivaut à:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
Cependant, il existe des variantes. Par exemple, si l'énumérateur (tmp) prend en charge IDisposable, il est également utilisé (similaire à using).
Notez la différence dans le placement de la déclaration " int i" à l' intérieur (C # 5.0) par rapport à l' extérieur (jusqu'à C # 4.0) de la boucle. C'est important si vous utilisez idans une méthode anonyme / lambda dans votre bloc de code. Mais c'est une autre histoire ;-p
+1 pour approfondir. Normalement, je ne vais pas plus en profondeur pour une question qui peut être une question «débutante» car elle semblerait accablante pour le nouveau programmeur.
George Stocker
C'est vrai, Gortok - donc j'ai suivi avec les trucs sur les listes / tableaux / etc.
Marc Gravell
Il serait bon de mentionner la conversion implicite du runtime en variable de boucle - peut produire des exceptions d'incompatibilité de type.
Daniel Earwicker du
3
N'oubliez pas: lorsque vous utilisez un tableau avec foreach, le compilateur crée un simple for-loop(vous pouvez le voir lorsque vous travaillez avec IL).
Felix K.
1
@Marc Gravell: OK, cool! J'ai édité l'article pour le rendre plus clair - du moins pour moi. Après tout, le placement n'est pas seulement important en C # 5.0, il est toujours important, seulement qu'il a changé. J'espère que cela ne vous dérange pas.
L' foreachinstruction répète un groupe d'instructions incorporées pour chaque élément d' un tableau ou d'une collection d'objets . L' foreachinstruction est utilisée pour parcourir la collection pour 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 ceci:
curieusement, selon MSDN ( msdn.microsoft.com/en-us/library/9yb8xew9(VS.80).aspx ), les types d'objets n'ont pas besoin d'implémenter IEnumerable. Tout type qui définit GetEnumerator, MoveNext, Reset et Current de la bonne manière fonctionnera. Bizarre, hein?
Sean Reilly
Soigné. Je ne savais pas ça. :-)
George Stocker
4
Selon le billet de blog Duck Notation , le typage canard est utilisé.
Il est important de noter que "Le type de l'élément de collection doit être convertible en type d'identifiant". Cela ne peut parfois 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 attribuable au type de référence.
Cela générera une exception d'exécution s'il y a un non-Apple dans la corbeille de fruits, comme une orange.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
Cela filtre en toute sécurité la liste uniquement pour les pommes à l'aide de Enumerable.OfType
List<int> numbers = new List<int>();
numbers.Add(5);
numbers.Add(15);
numbers.Add(25);
numbers.Add(35);
Console.WriteLine("You are added total number: {0}",numbers.Count);
foreach (int number in numbers)
{
Console.WriteLine("Your adding Number are: {0}", number);
}
Réponses:
En fait, à proprement parler, tout ce dont vous avez besoin
foreach
est uneGetEnumerator()
méthode publique qui renvoie quelque chose avec unebool MoveNext()
méthode et une? Current {get;}
propriété. Cependant, la signification la plus courante de ceci est "quelque chose qui implémenteIEnumerable
/IEnumerable<T>
, retournant unIEnumerator
/IEnumerator<T>
.Implicitement, cela inclut tout ce qui met en œuvre
ICollection
/ICollection<T>
, comme quelque chose commeCollection<T>
,List<T>
, les tableaux (T[]
), etc. Ainsi , toute « collecte de données » standard supportent en généralforeach
.Pour preuve du premier point, ce qui suit 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 marche?
Une boucle foreach comme
foreach(int i in obj) {...}
un peu é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 existe des variantes. Par exemple, si l'énumérateur (tmp) prend en charge
IDisposable
, il est également utilisé (similaire àusing
).Notez la différence dans le placement de la déclaration "
int i
" à l' intérieur (C # 5.0) par rapport à l' extérieur (jusqu'à C # 4.0) de la boucle. C'est important si vous utilisezi
dans une méthode anonyme / lambda dans votre bloc de code. Mais c'est une autre histoire ;-pla source
for-loop
(vous pouvez le voir lorsque vous travaillez avec IL).Depuis MSDN :
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 parcourir une
List<T>
collection, comme ceci:List<string> list = new List<string>(); foreach (string item in list) { Console.WriteLine(item); }
la source
Selon le billet de blog Duck Notation , le typage canard est utilisé.
la source
Voici la documentation: Article principal avec des tableaux avec des objets de collection
Il est important de noter que "Le type de l'élément de collection doit être convertible en type d'identifiant". Cela ne peut parfois 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 attribuable au type de référence.
Cela générera une exception d'exécution s'il y a un non-Apple dans la corbeille de fruits, comme une orange.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() }; foreach(Apple a in fruitBasket)
Cela filtre en toute sécurité la liste uniquement pour les pommes à l'aide de Enumerable.OfType
foreach(Apple a in fruitBasket.OfType<Apple>() )
la source
IList<ListItem> illi = new List<ListItem>(); ListItem li = null; foreach (HroCategory value in listddlsubcategory) { listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id); li = new ListItem(); li.Text = value.Description; li.Value = value.Id.ToString(); illi.Add(li); IList<ListItem> newilli = new List<ListItem>(); newilli = SubCatagoryFunction(listddlsubcategoryext, "-->"); foreach (ListItem c in newilli) { illi.Add(c); } }
la source
Des informations utiles à ce sujet sont également disponibles sur MSDN . Prenant l'essence de cet article:
Le mot clé foreach énumère une collection, en exécutant l'instruction incorporée une fois pour chaque élément de la collection:
foreach (var item in collection) { Console.WriteLine(item.ToString()); }
Le compilateur traduit la boucle foreach illustrée dans l'exemple ci-dessus en quelque chose de similaire à cette construction:
IEnumerator<int> enumerator = collection.GetEnumerator(); while (enumerator.MoveNext()) { var item = enumerator.Current; Console.WriteLine(item.ToString()); }
la source
vous pouvez essayer ceci ...
List<int> numbers = new List<int>(); numbers.Add(5); numbers.Add(15); numbers.Add(25); numbers.Add(35); Console.WriteLine("You are added total number: {0}",numbers.Count); foreach (int number in numbers) { Console.WriteLine("Your adding Number are: {0}", number); }
la source