0Pricing
C# Academy · Lezione

yield break e terminazione anticipata

Arresti l'iterazione in modo condizionale.

yield break e terminazione anticipata è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Arrestare anticipatamente un iteratore

A volte si desidera che un iteratore smetta di produrre valori prima di raggiungere il termine naturale. L'istruzione yield break termina immediatamente la sequenza, come un return per gli iteratori.

yield break di base

yield break termina l'iteratore. Non vengono prodotti altri valori e il ciclo foreach che lo consuma termina.

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

Prendere elementi finché una condizione è vera

Un modello comune consiste nel restituire elementi solo finché una condizione è vera, quindi fermarsi. yield break rende questo approccio semplice e chiaro.

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

Clausole di guardia con yield break

È possibile usare yield break all'inizio di un iteratore come clausola di guardia. Se l'input è vuoto o non valido, non viene restituito alcun elemento.

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());
    }
}

Limitare il numero di elementi restituiti

Usi un contatore insieme a yield break per limitare il numero di elementi prodotti da un iteratore, anche a partire da una sorgente molto lunga.

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

break del chiamante e yield break

Una sequenza può terminare in due modi. Il chiamante può smettere di richiedere elementi usando break, oppure l'iteratore può smettere di produrli usando yield break. Entrambi terminano il ciclo, ma per motivi diversi.

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 termina solo l'iteratore corrente

yield break esce dal metodo iteratore in cui compare, non da un eventuale ciclo esterno nel chiamante. Il controllo torna al codice che stava enumerando la sequenza.

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

Nessun yield return dopo yield break

Quando viene eseguito yield break, l'iteratore è terminato. Il codice che si trova fisicamente dopo quell'istruzione nello stesso percorso non può produrre valori.

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

Combinare il filtro e l'arresto anticipato

È possibile filtrare e terminare nello stesso iteratore: si saltano alcuni valori, se ne restituiscono altri e si interrompe completamente l'elaborazione quando compare un valore sentinella.

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

Blocchi yield break e finally

Se l'iteratore contiene un try/finally, il blocco finally viene comunque eseguito quando yield break termina la sequenza. Questo garantisce operazioni di pulizia come la chiusura delle risorse.

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

Provi personalmente

Combini il filtraggio e l'interruzione anticipata: restituisca i numeri positivi, ma interrompa tutto non appena la loro somma progressiva supera un limite.

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

Verifica rapida

Ricordi il ruolo di yield break.

Riepilogo

yield break termina anticipatamente un iteratore.

  • Funziona come un return senza valore per gli iteratori.
  • Lo usi per la logica take-while, i controlli preliminari e i limiti di conteggio.
  • Termina solo l'iteratore, non il ciclo chiamante.
  • I blocchi finally vengono comunque eseguiti, garantendo la pulizia.

Domande Frequenti

La lezione «yield break e terminazione anticipata» è gratuita?

Sì — il testo completo di «yield break e terminazione anticipata» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «yield break e terminazione anticipata»?

Arresti l'iterazione in modo condizionale. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «yield break e terminazione anticipata»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Metodi iteratori con yield return
  2. yield break e terminazione anticipata
  3. Semantica della valutazione lazy
  4. Enumerabili personalizzati
← Torna a C# Academy