C# Academy · Oppitunti

yield break ja iteraation ennenaikainen lopetus

Pysäyttäkää iterointi ehdollisesti.

Oppitunti 2/413 vaihetta

yield break ja iteraation ennenaikainen lopetus on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.

Iteraattorin aikainen pysäyttäminen

Joskus iteraattorin halutaan lopettavan arvojen tuottamisen ennen luonnollista loppua. yield break -lause päättää sekvenssin välittömästi, kuten return iteraattoreita käytettäessä.

yield break -lauseen perusteet

yield break lopettaa iteraattorin. Enempää arvoja ei tuoteta, ja sitä kuluttava foreach-silmukka päättyy.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> UpToFive()
    {
        for (int i = 1; i <= 100; i++)
        {
            if (i > 5) yield break;
            yield return i;
        }
    }

    public static void Main()
    {
        foreach (var n in UpToFive())
            Console.WriteLine(n);
    }
}

Alkioiden ottaminen ehdon täyttyessä

Yleinen toimintamalli on tuottaa alkioita vain niin kauan kuin ehto on tosi ja lopettaa sen jälkeen. yield break tekee tästä selkeää.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> WhileSmall(IEnumerable<int> nums)
    {
        foreach (var n in nums)
        {
            if (n >= 10) yield break;
            yield return n;
        }
    }

    public static void Main()
    {
        foreach (var n in WhileSmall(new[] { 2, 4, 8, 12, 3 }))
            Console.WriteLine(n);
    }
}

Suojausehdot yield break -lauseella

yield break -lausetta voidaan käyttää iteraattorin alussa suojausehtona. Jos syöte on tyhjä tai virheellinen, metodi ei palauta lainkaan alkioita.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static IEnumerable<string> Lines(string text)
    {
        if (string.IsNullOrEmpty(text)) yield break;
        foreach (var line in text.Split('\n'))
            yield return line;
    }

    public static void Main()
    {
        foreach (var l in Lines("a\nb\nc"))
            Console.WriteLine(l);
        Console.WriteLine("empty count: " + Lines("").Count());
    }
}

Tulosten määrän rajoittaminen

Laskurin ja yield break -lauseen avulla voidaan rajoittaa iteraattorin tuottamien alkioiden määrää myös pitkän lähteen tapauksessa.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Take(IEnumerable<int> source, int max)
    {
        int count = 0;
        foreach (var item in source)
        {
            if (count++ >= max) yield break;
            yield return item;
        }
    }

    public static void Main()
    {
        foreach (var n in Take(new[] { 1, 2, 3, 4, 5 }, 3))
            Console.WriteLine(n);
    }
}

Kutsujan break vai yield break

Sekvenssi voi päättyä kahdella tavalla. Kutsuja voi lopettaa arvojen pyytämisen break-lauseella, tai iteraattori voi lopettaa niiden tuottamisen yield break -lauseella. Molemmat päättävät silmukan, mutta eri syystä.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Counting()
    {
        int i = 1;
        while (true) yield return i++;
    }

    public static void Main()
    {
        // Caller decides to stop with break
        foreach (var n in Counting())
        {
            if (n > 3) break;
            Console.WriteLine(n);
        }
    }
}

yield break päättää vain nykyisen iteraattorin

yield break poistuu siitä iteraattorimetodista, jossa se esiintyy, ei kutsujan ulommasta silmukasta. Suoritus palautuu sille, joka kävi sekvenssiä läpi.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Bounded(IEnumerable<int> nums, int limit)
    {
        foreach (var n in nums)
        {
            if (n > limit) yield break; // ends Bounded only
            yield return n;
        }
    }

    public static void Main()
    {
        var result = Bounded(new[] { 1, 2, 9, 3 }, 5);
        Console.WriteLine("iterator created, still running");
        foreach (var n in result) Console.WriteLine(n);
    }
}

Ei yield return -lauseita yield break -lauseen jälkeen

Kun yield break suoritetaan, iteraattori on valmis. Sen jälkeen samassa suorituspolussa fyysisesti oleva koodi ei voi tuottaa arvoja.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Demo(bool stopEarly)
    {
        yield return 1;
        if (stopEarly) yield break;
        yield return 2;
        yield return 3;
    }

    public static void Main()
    {
        Console.WriteLine("stopEarly = true:");
        foreach (var n in Demo(true)) Console.WriteLine(n);
        Console.WriteLine("stopEarly = false:");
        foreach (var n in Demo(false)) Console.WriteLine(n);
    }
}

Suodattamisen ja aikaisen pysäytyksen yhdistäminen

Suodatus ja lopettaminen voidaan yhdistää samaan iteraattoriin: osa arvoista ohitetaan, osa tuotetaan ja suoritus lopetetaan kokonaan, kun tietty merkkiarvo tulee vastaan.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> UntilZero(IEnumerable<int> nums)
    {
        foreach (var n in nums)
        {
            if (n == 0) yield break;     // stop at sentinel
            if (n < 0) continue;         // skip negatives
            yield return n;
        }
    }

    public static void Main()
    {
        foreach (var n in UntilZero(new[] { 3, -1, 5, 0, 9 }))
            Console.WriteLine(n);
    }
}

yield break- ja finally-lohkot

Jos iteraattorissanne on try/finally, finally suoritetaan edelleen, kun yield break lopettaa sekvenssin. Näin varmistetaan esimerkiksi resurssien sulkemisen kaltaiset siivoustoimet.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> WithCleanup()
    {
        try
        {
            yield return 1;
            yield break;
        }
        finally
        {
            Console.WriteLine("cleanup ran");
        }
    }

    public static void Main()
    {
        foreach (var n in WithCleanup())
            Console.WriteLine(n);
    }
}

Kokeilkaa itse

Yhdistäkää suodatus ja ennenaikainen lopetus: palauttakaa positiivisia lukuja, mutta lopettakaa kokonaan heti, kun niiden kumulatiivinen summa ylittää budjetin.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> WithinBudget(IEnumerable<int> nums, int budget)
    {
        int spent = 0;
        foreach (var n in nums)
        {
            if (n <= 0) continue;
            if (spent + n > budget) yield break;
            spent += n;
            yield return n;
        }
    }

    public static void Main()
    {
        foreach (var n in WithinBudget(new[] { 3, -2, 4, 5, 1 }, 10))
            Console.WriteLine(n);
    }
}

Pikatarkistus

Palauttakaa mieleenne yield break-lauseen tehtävä.

Kertaus

yield break lopettaa iteraattorin ennenaikaisesti.

  • Se toimii iteraattoreissa arvoa palauttamattoman return-lauseen tavoin.
  • Käyttäkää sitä while-tyyppiseen valintalogiikkaan, suojauksiin ja lukumäärärajoihin.
  • Se lopettaa vain iteraattorin, ei kutsujan silmukkaa.
  • finally-lohkot suoritetaan edelleen, joten siivoustoimet varmistetaan.
Aloita maksutta

Opi C# tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
93
Oppitunnit
346

Usein kysytyt kysymykset

Onko oppitunti ”yield break ja iteraation ennenaikainen lopetus” ilmainen?

Kyllä – oppitunnin ”yield break ja iteraation ennenaikainen lopetus” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”yield break ja iteraation ennenaikainen lopetus”?

Pysäyttäkää iterointi ehdollisesti. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”yield break ja iteraation ennenaikainen lopetus”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?

Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Iteraattorimetodit yield return -lauseella
  2. yield break ja iteraation ennenaikainen lopetus
  3. Laiskan evaluoinnin semantiikka
  4. Mukautetut enumerable-tyypit
← Takaisin: C# Academy