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 itérateur est terminé. Vous pouvez considérer yield break
comme une instruction return
qui ne renvoie pas de valeur.
Par exemple, si vous définissez une fonction en tant qu'itérateur, 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 ceci avec 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 tôt.
Termine un bloc itérateur (par exemple, indique qu'il n'y a plus d'éléments dans IEnumerable).
Dit à l'itérateur qu'il a atteint la fin.
Par exemple:
public interface INode
{
IEnumerable<Node> GetChildren();
}
public class NodeWithTenChildren : INode
{
private Node[] m_children = new Node[10];
public IEnumerable<Node> GetChildren()
{
for( int n = 0; n < 10; ++n )
{
yield return m_children[ n ];
}
}
}
public class NodeWithNoChildren : INode
{
public IEnumerable<Node> GetChildren()
{
yield break;
}
}
yield
rend fondamentalement une méthode IEnumerable<T>
se comporter de la même manière qu'un thread planifié en coopération (par opposition à préemptivement).
yield return
est comme un fil appelant une fonction "emploi du temps" ou "veille" pour abandonner le contrôle de la CPU. Tout comme un thread, la méthode IEnumerable<T>
reprend les contrôles au point immédiatement après, toutes les variables locales ayant les mêmes valeurs qu'avant la suppression du 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 vraiment un "fil". Un thread a un certain état (c'est-à-dire des valeurs de variables locales) et, chaque fois qu'il est programmé, il effectue des actions pour atteindre un nouvel état. Le point clé à propos de yield
est que, contrairement aux threads du système d’exploitation auxquels nous sommes habitués, le code qui l’utilise est figé dans le temps jusqu’à ce que l’itération soit avancée ou terminée manuellement.
Le sujet entier des blocs d'itérateurs est bien traité dans ce chapitre d'échantillons gratuits tiré du livre de Jon Skeet C # in Depth .
Voici http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ est un très bon exemple:
public statique IEnumerable <int> Plage (int min, int max) { tant que (vrai) { if (min> = max) { rupture de rendement; } rendement retour min ++; } }
et explication, que si une instruction yield break
est touchée dans une méthode, l'exécution de cette méthode s'arrête sans retour. Dans certaines situations, lorsque vous ne voulez donner aucun résultat, vous pouvez utiliser la limite de rendement.
L'instruction yield break
provoque l'arrêt de l'énumération. En effet, yield break
termine l'énumération sans renvoyer d'éléments supplémentaires.
Considérez qu’une méthode itérateur peut arrêter d’itérer de deux manières. Dans un cas, la logique de la méthode pourrait naturellement sortir de la méthode après avoir renvoyé tous les éléments. Voici un exemple:
IEnumerable<uint> 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 itérateur cessera naturellement de s'exécuter une fois que maxCount
nombres premiers ont été trouvés.
L'instruction yield break
est un autre moyen pour l'itérateur de cesser d'énumérer. C'est un moyen de sortir du recensement plus tôt. Voici la même méthode que ci-dessus. Cette fois, la méthode a une limite sur le temps que la méthode peut exécuter.
IEnumerable<uint> 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 sort du recensement plus tôt.
Notez aussi que le yield break
fonctionne différemment d’un simple break
. Dans l'exemple ci-dessus, yield break
quitte la méthode sans appeler l'appel de Debug.WriteLine(..)
.
Si vous voulez dire "qu'est-ce que la rupture de rendement fait vraiment", 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 itérateurs C # génèrent du code très compliqué.
rupture de rendement est juste une façon de dire retour pour la dernière fois et ne renvoient aucune valeur
par exemple
// returns 1,2,3,4,5
IEnumerable<int> 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;
}