yield break og tidlig afslutning
Stop gennemløbet betinget.
yield break og tidlig afslutning er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.
Tidligt stop af en iterator
Nogle gange vil du have en iterator til at stoppe med at producere værdier, før den når sin naturlige afslutning. Sætningen yield break afslutter sekvensen med det samme, ligesom et return for iteratorer.
Grundlæggende yield break
yield break afslutter iteratoren. Der produceres ikke flere værdier, og foreach-løkken, der gennemløber den, afsluttes.
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);
}
}Tag værdier, mens en betingelse gælder
Et almindeligt mønster er kun at levere elementer, så længe en betingelse er sand, og derefter stoppe. yield break gør dette enkelt.
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);
}
}Værn om inddata med yield break
Du kan bruge yield break øverst i en iterator som en kontrol. Hvis inddataene er tomme eller ugyldige, returneres ingen elementer overhovedet.
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());
}
}Begrænsning af antallet af uddata
Brug en tæller sammen med yield break til at begrænse, hvor mange elementer en iterator producerer, selv fra en lang kilde.
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);
}
}Kaldende kode: break kontra yield break
En sekvens kan slutte på to måder. Den kaldende kode kan stoppe med at hente værdier ved hjælp af break, eller iteratoren kan stoppe med at producere værdier ved hjælp af yield break. Begge afslutter løkken, men af forskellige årsager.
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 afslutter kun den aktuelle iterator
yield break afslutter den iteratormetode, den står i, ikke en ydre løkke i den kaldende kode. Styringen vender tilbage til den kode, der gennemløb sekvensen.
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);
}
}Intet yield return efter yield break
Når yield break udføres, er iteratoren færdig. Kode, der står fysisk efter den i samme udførelsessti, kan ikke producere værdier.
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);
}
}Kombination af filtrering og tidligt stop
Du kan filtrere og afslutte i den samme iterator: spring nogle værdier over, lever andre, og afslut helt, når der dukker en stopmarkør op.
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 og finally-blokke
Hvis din iterator indeholder en try/finally, kører finally stadig, når yield break afslutter sekvensen. Det sikrer oprydning, f.eks. at ressourcer lukkes.
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);
}
}Prøv selv
Kombinér filtrering og tidlig afslutning: brug yield til at levere positive tal, men stop helt, så snart deres løbende sum overskrider et budget.
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);
}
}Hurtigt tjek
Genopfrisk rollen for yield break.
Opsummering
yield break afslutter en iterator før tid.
- Det fungerer som en
returnuden værdi for iteratorer. - Brug det til logik, der tager elementer, så længe en betingelse er opfyldt, til kontrolbetingelser og til begrænsning af antallet.
- Det afslutter kun iteratoren, ikke den kaldende løkke.
finally-blokke kører stadig, så oprydning er sikret.
Lær C# med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 93
- Lektioner
- 346
Ofte stillede spørgsmål
Er lektionen “yield break og tidlig afslutning” gratis?
Ja — hele teksten til “yield break og tidlig afslutning” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “yield break og tidlig afslutning”?
Stop gennemløbet betinget. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på C# Academy?
Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “yield break og tidlig afslutning”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne C# Academy-lektion?
Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Iteratormetoder med yield return
- yield break og tidlig afslutning
- Semantik for lazy evaluering
- Brugerdefinerede enumerables