Que fait "yield break" Dans C#?

j'ai vu cette syntaxe dans MSDN: yield break , mais je ne sais pas ce que ça fait. Personne ne sait?

417
demandé sur Zach Saucier 2008-10-24 03:07:02

10 réponses

il spécifie qu'un itérateur est arrivé à sa fin. Vous pouvez penser à yield break comme une déclaration return qui ne renvoie pas de valeur.

Par exemple, si vous définissez une fonction comme un 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 qu'après que 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 parce que nous avons quitté la fonction tôt.

448
répondu Damir Zekić 2016-08-19 12:34:33

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

46
répondu Brian 2008-10-23 23:09:09

indique à l'itérateur qu'il a atteint la fin.

comme 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
répondu Trap 2008-10-23 23:24:41

yield rend fondamentalement une méthode IEnumerable<T> se comporte de la même manière qu'un filetage programmé coopératif (par opposition à un filetage préemptif).

yield return est comme un fil appelant une fonction "schedule" ou "sleep" pour abandonner le contrôle du CPU. Tout comme un thread, la méthode IEnumerable<T> récupère les contrôles au point immédiatement après, toutes les variables locales ayant les mêmes valeurs qu'avant l'abandon du contrôle.

yield break est comme un fil qui atteint la fin de sa fonction et se termine.

les gens parlent d'une "machine d'état", mais une machine d'état est tout un" fil " est vraiment. Un fil a un certain état (c'est-à-dire. valeurs des variables locales), et chaque fois qu'elle est programmée, elle prend des mesures 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é manuellement ou terminé.

18
répondu 2009-06-26 20:33:37

tout le sujet des blocs itérateurs est bien traité dans ce chapitre échantillon gratuit du livre de Jon Skeet C# en profondeur .

10
répondu Marc Gravell 2016-09-01 18:16:03

ici http://www.alteridem.net/2007/08/22/the-yield-statement-in-c / est un très bon exemple:

public static IEnumerable<int> Range( int min, int max )
{
   while ( true )
   {
      if ( min >= max )
      {
         yield break;
      }
      yield return min++;
   }
}

et explication, que si une instruction yield break est frappée dans une méthode, l'exécution de cette méthode s'arrête sans retour. Il y a des situations de temps, quand vous ne voulez pas donner de résultat, alors vous pouvez utiliser la limite de rendement.

7
répondu Towhid 2011-05-19 05:12:24

l'énoncé yield break fait cesser l'énumération. En fait, yield break complète le recensement sans retourner d'éléments supplémentaires.

considérer qu'il y a en fait deux façons dont une méthode itératrice pourrait arrêter itérating. Dans un cas, la logique de la méthode pourrait naturellement sortir de la méthode après avoir retourné 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 iterator naturellement arrêter l'exécution une fois que les amorces maxCount ont été trouvées.

l'énoncé yield break est une autre façon pour l'itérateur de cesser d'énumérer. C'est un moyen de sortir de l'énumération tôt. Ici c'est la même méthode que ci-dessus. Cette fois, la méthode a une limite sur la quantité de temps que la méthode peut s'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 fait, il sort de l'énumération plus tôt.

remarquez aussi que le yield break fonctionne différemment d'un simple break . Dans l'exemple ci-dessus, yield break sort de la méthode sans faire l'appel à Debug.WriteLine(..) .

5
répondu Wally 2016-11-26 01:22:56

si ce que vous voulez dire par "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

C# itérateurs peu de code compliqué.

4
répondu Tony Lee 2011-08-29 17:13:01

yield break est juste une façon de dire retour pour la dernière fois et ne pas renvoyer une valeur

E. g

// 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;
 }
-1
répondu John ClearZ 2018-07-24 15:13:03

le mot-clé yield est utilisé avec le mot-clé return pour fournir une valeur à l'objet enumerator. taux de retour spécifie la valeur ou les valeurs retournées. Lorsque la déclaration de rendement est atteinte, l'emplacement courant est stocké. L'exécution est redémarrée à partir de cet emplacement la prochaine fois que l'itérateur est appelé.

pour expliquer le sens à l'aide d'un exemple:

    public IEnumerable<int> SampleNumbers()
    {
        int counter = 0;
        yield return counter;

        counter = counter + 2;

        yield return counter;

        counter = counter + 3;

        yield return counter ;
    }

Les valeurs retournées lors de cette itération sont: 0, 2, 5.

il est important de noter que la variable counter dans cet exemple est une variable locale. après la deuxième itération qui renvoie la valeur de 2, la troisième itération commence là où elle est partie avant, tout en conservant la valeur précédente de la variable locale appelée counter qui était 2.

-2
répondu Eranga Dissanayaka 2012-02-15 15:43:39