J’ai vu cette syntaxe dans MSDN: yield break
, mais je ne sais pas ce que ça fait. Est-ce que quelqu’un sait?
Il spécifie qu’un iterator a pris fin. Vous pouvez penser yield break
de yield break
comme une déclaration de return
qui ne renvoie pas de valeur.
Par exemple, si vous définissez une fonction en tant qu’iterator, le corps de la fonction peut ressembler à ceci:
for (int i = 0; i < 5; i++) { yield return i; } Console.Out.WriteLine("You will see me");
Notez que lorsque la boucle a terminé tous ses cycles, la dernière ligne est exécutée et vous verrez le message dans votre application de console.
Ou comme ça avec la yield break
:
int i = 0; while (true) { if (i < 5) { yield return i; } else { // note that i++ will not be executed after this yield break; } i++; } Console.Out.WriteLine("Won't see me");
Dans ce cas, la dernière instruction n'est jamais exécutée car nous avons quitté la fonction plus tôt.
Termine un bloc d’iterator (par exemple, il n’y a plus d’éléments dans IEnumerable).
Indique à l’iterator qu’il a atteint la fin.
Par exemple:
public interface INode { IEnumerable GetChildren(); } public class NodeWithTenChildren : INode { private Node[] m_children = new Node[10]; public IEnumerable GetChildren() { for( int n = 0; n < 10; ++n ) { yield return m_children[ n ]; } } } public class NodeWithNoChildren : INode { public IEnumerable GetChildren() { yield break; } }
yield
permet à une méthode IEnumerable
se comporter de manière similaire à un thread planifié en coopération (par opposition à préemptivement).
yield return
est comme un thread appelant une fonction “schedule” ou “sleep” pour abandonner le contrôle du CPU. Tout comme un thread, la méthode IEnumerable
récupère les contrôles immédiatement après, toutes les variables locales ayant les mêmes valeurs qu’avant le contrôle.
yield break
est comme un fil atteignant la fin de sa fonction et se terminant.
Les gens parlent d’une “machine à états”, mais une machine à états est tout ce qu’un “fil” est vraiment. Un thread a un état (Ie valeurs des variables locales), et chaque fois qu’il est programmé, il lui faut une ou plusieurs actions pour atteindre un nouvel état. Le point clé concernant le yield
est que, contrairement aux threads du système d’exploitation auxquels nous sums habitués, le code qui l’utilise est figé dans le temps jusqu’à ce que l’itération soit manuellement avancée ou terminée.
Le sujet entier des blocs d’iterators est bien couvert dans ce chapitre gratuit du livre C # in Depth de Jon Skeet.
Voici http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ est un très bon exemple:
statique publique IEnumerablePlage (int min, int max) { tandis que (vrai) { si (min> = max) { rupture de rendement; } rendement rendement min ++; } }
et explication, que si une déclaration de yield break
est atteinte dans une méthode, l’exécution de cette méthode s’arrête sans retour. Il y a des situations de temps où vous ne voulez pas donner de résultat, alors vous pouvez utiliser la rupture de rendement.
L’instruction yield break
entraîne l’arrêt de l’énumération. En effet, la yield break
complète l’énumération sans renvoyer d’éléments supplémentaires.
Considérez qu’une méthode d’itération peut arrêter l’itération de deux manières. Dans un cas, la logique de la méthode pourrait naturellement quitter la méthode après avoir renvoyé tous les éléments. Voici un exemple:
IEnumerable FindPrimes(uint startAt, uint maxCount) { for (var i = 0UL; i < maxCount; i++) { startAt = NextPrime(startAt); yield return startAt; } Debug.WriteLine("All the primes were found."); }
Dans l'exemple ci-dessus, la méthode iterator cessera naturellement de s'exécuter une fois que maxCount
primes aura été trouvé.
L'instruction yield break
est un autre moyen pour l'iterator de cesser d'énumérer. C'est un moyen de sortir de l'énumération plus tôt. Voici la même méthode que ci-dessus. Cette fois, la méthode limite la durée d'exécution de la méthode.
IEnumerable FindPrimes(uint startAt, uint maxCount, int maxMinutes) { var sw = System.Diagnostics.Stopwatch.StartNew(); for (var i = 0UL; i < maxCount; i++) { startAt = NextPrime(startAt); yield return startAt; if (sw.Elapsed.TotalMinutes > maxMinutes) yield break; } Debug.WriteLine("All the primes were found."); }
Notez l'appel à yield break
. En effet, il quitte le dénombrement tôt.
Notez également que la yield break
fonctionne différemment d'une simple break
. Dans l'exemple ci-dessus, la yield break
quitte la méthode sans appeler Debug.WriteLine(..)
.
Si ce que vous voulez dire par “ce que fait réellement la rupture, c’est” comment ça marche “- Voir le blog de Raymond Chen pour plus de détails http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519. aspx
Les iterators C # génèrent un code très compliqué.
la rupture de rendement est juste un moyen de dire le retour pour la dernière fois et ne retourne aucune valeur
par exemple
// returns 1,2,3,4,5 IEnumerable CountToFive() { yield return 1; yield return 2; yield return 3; yield return 4; yield return 5; yield break; yield return 6; yield return 7; yield return 8; yield return 9; }
Le mot-clé yield est utilisé avec le mot-clé return pour fournir une valeur à l’object énumérateur. return return spécifie la ou les valeurs renvoyées. Lorsque la déclaration de rendement est atteinte, l’emplacement actuel est stocké. L’exécution est redémarrée à partir de cet emplacement la prochaine fois que l’iterator est appelé.
Expliquer le sens en utilisant un exemple:
public IEnumerable
SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; }
Les valeurs renvoyées lors de l’itération sont: 0, 2, 5.
Il est important de noter que la variable compteur dans cet exemple est une variable locale. Après la deuxième itération qui renvoie la valeur 2, la troisième itération commence à l’endroit où elle était avant, tout en conservant la valeur précédente de la variable locale nommée counter qui était 2.