Co robi "yield break;" w C#?

Widziałem tę składnię w MSDN: yield break, ale nie wiem, co to robi. Czy ktoś wie?

 417
Author: Zach Saucier, 2008-10-24

10 answers

Określa, że iterator dobiegł końca. Możesz myśleć o yield break jako o instrukcji return, która nie zwraca wartości.

Na przykład, jeśli zdefiniujesz funkcję jako iterator, ciało funkcji może wyglądać następująco:

for (int i = 0; i < 5; i++)
{
    yield return i;
}

Console.Out.WriteLine("You will see me");

Zauważ, że po zakończeniu wszystkich cykli pętli, ostatnia linia zostanie wykonana i zobaczysz wiadomość w aplikacji konsoli.

Lub tak z 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");

W tym przypadku ostatnie polecenie nigdy nie jest wykonywane bo wcześniej wyszliśmy z pracy.

 448
Author: Damir Zekić,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 12:34:33

Kończy blok iteratora(np. mówi, że nie ma więcej elementów w IEnumerable).

 46
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 23:09:09

Mówi iteratorowi, że osiągnął koniec.

Jako przykład:

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
Author: Trap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 23:24:41

yield zasadniczo sprawia, że metoda IEnumerable<T> zachowuje się podobnie do cooperatywnie (w przeciwieństwie do prewencyjnie) zaplanowanego wątku.

yield return jest jak wątek wywołujący funkcję " schedule "lub " sleep", aby zrezygnować z kontroli nad procesorem. Podobnie jak w wątku, metoda IEnumerable<T> odzyskuje kontrole w punkcie natychmiast po tym, gdy wszystkie zmienne lokalne mają takie same wartości, jakie miały przed rezygnacją z kontroli.

yield break jest jak nić sięgająca końca swojej funkcji i kończę.

Ludzie mówią o "maszynie stanowej", ale maszyna stanowa to wszystko "wątek" naprawdę jest. Wątek ma jakiś stan (np. wartości zmiennych lokalnych) i za każdym razem, gdy jest zaplanowany, podejmuje jakieś działania w celu osiągnięcia nowego stanu. Kluczowym punktem yield jest to, że w przeciwieństwie do wątków systemu operacyjnego, do których jesteśmy przyzwyczajeni, kod, który go używa, jest zamrożony w czasie, aż iteracja zostanie ręcznie zaawansowana lub zakończona.

 18
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-26 20:33:37

Cały temat bloków iteratora jest dobrze omówiony w tym darmowym rozdziale przykładowym z książki Jona Skeeta C # in Depth.

 10
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-01 18:16:03

Tutaj http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ jest bardzo dobrym przykładem:

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

I Wyjaśnienie, że jeśli polecenie yield break zostanie wywołane wewnątrz metody, wykonywanie tej metody zatrzymuje się bez powrotu. Są pewne sytuacje czasowe, kiedy nie chcesz dać żadnego rezultatu, możesz użyć yield break.

 7
Author: Towhid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-19 05:12:24

Instrukcja yield break powoduje zatrzymanie wyliczenia. W efekcie yield break kończy wyliczenie bez zwracania żadnych dodatkowych elementów.

Weźmy pod uwagę, że istnieją dwa sposoby, w jakie metoda iteratora mogłaby przestać iterację. W jednym przypadku logika metody może w naturalny sposób zakończyć metodę po zwróceniu wszystkich elementów. Oto przykład:

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.");
}

W powyższym przykładzie, metoda iteratora w naturalny sposób przestanie działać, gdy maxCount Liczby pierwsze zostaną znaleziono.

Twierdzenie yield break jest kolejnym sposobem, aby iterator zaprzestał wyliczania. Jest to sposób na wczesne wyrwanie się z wyliczenia. Oto ta sama metoda jak powyżej. Tym razem metoda ma limit czasu, jaki metoda może wykonać.

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.");
}

Zwróć uwagę na wezwanie do yield break. W efekcie, to wychodzi z wyliczenia wcześnie.

Zauważ też, że yield break działa inaczej niż zwykły break. W powyższym przykładzie yield break kończy działanie metody bez wykonanie połączenia do Debug.WriteLine(..).

 5
Author: Wally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 01:22:56

Jeśli masz na myśli "co naprawdę robi yield break", to "jak to działa" - zobacz blog Raymonda Chena po szczegóły http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx

Iteratory C # generują bardzo skomplikowany kod.

 4
Author: Tony Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-29 17:13:01

Yield break jest tylko sposobem na powiedzenie return po raz ostatni i nie zwracaj żadnej wartości

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
Author: John ClearZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 15:13:03

Słowo kluczowe yield jest używane razem ze słowem kluczowym return w celu dostarczenia wartości do obiektu enumerator. yield return określa zwracaną wartość lub wartości. Po osiągnięciu instrukcji zwrotu wydajności zapisywana jest bieżąca lokalizacja. Wykonanie jest restartowane z tej lokalizacji przy następnym wywołaniu iteratora.

Aby wyjaśnić znaczenie za pomocą przykładu:

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

        counter = counter + 2;

        yield return counter;

        counter = counter + 3;

        yield return counter ;
    }

Wartości zwracane podczas iteracji to: 0, 2, 5.

To ważne. należy zauważyć, że zmienna counter w tym przykładzie jest zmienną lokalną. po drugiej iteracji, która zwraca wartość 2, trzecia iteracja rozpoczyna się od miejsca, w którym pozostała wcześniej, zachowując poprzednią wartość zmiennej lokalnej o nazwie counter, która wynosiła 2.

 -2
Author: Eranga Dissanayaka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-15 15:43:39