web-dev-qa-db-fra.com

Qu'est-ce que "donne la rupture"; faire en C #?

J'ai vu cette syntaxe dans MSDN: yield break , mais je ne sais pas ce que ça fait. Est-ce que quelqu'un sait?

458
skb

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.

496
Damir Zekić

Termine un bloc itérateur (par exemple, indique qu'il n'y a plus d'éléments dans IEnumerable).

53
Brian

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;
    }
}
29
Trap

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.

20
Matthew

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 .

11
Marc Gravell

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.

7
Yuriy Zaletskyy

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(..).

7
Wallace Kelly

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é.

4
Tony Lee

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;
 }
3
John ClearZ