Bonjour,
La question que j'ai aujourd'hui concerne la différence entre l'usage du moit clé YIELD dans une boucle foreach et son non usage dans ce même type de boucle.
D'après ce que je connais , chaque interface IEnumerable<T>, doit définir une méthode GetEnumerator()
Cette méthode retourne un objet qui implémente l'interface IEnumerator<T>.
Cet objet retourné fournit la logique dont a besoin l'instruction foreach.
Cette instruction foreach fournit donc l'énumérateur par défaut dont on a besoin pour le parcours d'une collection.
voici un exemple de boucle foreach
Je peux donc considérer qu'à chaque fois que j'utilise la boucle foreach, j'utilise implicitement un objet de type IEnumerator qui contient les méthodes MoveNext et Reset ainsi que la property Current.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class CustomCollectionClass<T> : IEnumerable<T>{ public IEnumerator<T>GetEnumerator(){ ...... } CustomCollectionCalss<int> intCollection= new CustomCollectionClass<int>(); intCollection.Add(3); intCollection.Add(5); intCollection.Add(8); intCollection.Add(2); //la boucle foreach entraîne l'usage implicite de l'enumerateur par défaut foreach (int temp in intCollection){ } }
Par ailleurs, j'apprends que si j'utilise mot clé yield dans une boucle for, ainsi
Dans ce cas, la méthode GetEnumerator()ne retourne pas un objet de type IEnumerator<T> ,c'est à dire qui implémente les méthodes MoveNext et Reset ainsi que retourne la property Current(Ah bon!) .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 class BasicCollection<T>:IEnumerable<T>{ private List<T> data = new List<T>; public void FillList(params T[]items){ foreach(var datum in items) data.Add(datum); } IEnumerator<T>IEnumerable<T>.GetEnumerator(){ foreach (var datum in data){ yield return datum; } }
A la place elle boucle au niveau des éléménts de le collection data et retourne chaque élement l'un après l'autre(j'avoue que je ne vois pas la différence avec le fait d'appeler implicitement les méthodes moveNext et utiliser la property Current).
C'est le mot clé YIELD qui va permettre ce retour d'un objet de type IEnumerator<T>.
J'avoue que cela contredit ce que j'ai écris précédemment concernant l'usage d'un enumateur par défaut dans une boucle foreach
En effet,j'apprends que par l'usage du mot clé YIELD :
-la valeur concernée par chaque itération est renvoyée donc cela implique l'usage implicite de la property Current
-le passage à la prochaine valeur s'effectue grâce à l'appel implicite de la méthode MoveNext()
Le mot clé YIELD est utilisé par le compilateur pour générr une implémentation de l'interface IEnumerator<T< qui contient les méthodes MoveNext() et Reset()
ainsi que la property Current.
J'avoue que je ne vois pas la différence entre une simple boucle foreach , qui, si j'ai bien compris, utilise implicitement un objet de type IEnumerator<T> et l'usage du mot clé YIELD dans une boucle foreach pour boucler au niveau des éléments d'une collection.
Je vous remercie beaucoup de bien vouloir m'expliquer la différence exacte entre l'usage et le non usage de ce mot clé dans une boucle foreach.
Bien cordialement.
new_wave
Partager