0Pricing
C# Academy · Lezione

Metodi iteratori con yield return

Generi sequenze un elemento alla volta.

Metodi iteratori con yield return è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 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.

Che cos'è un metodo iteratore

Un metodo iteratore produce una sequenza di valori, uno alla volta, usando yield return. Il compilatore lo trasforma in una macchina a stati, quindi non è necessario creare e gestire autonomamente un elenco.

Il primo yield return

Ogni yield return restituisce un valore al chiamante e mette in pausa il metodo. L'esecuzione riprende subito dopo quell'istruzione nell'iterazione successiva.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> FirstThree()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }

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

yield return all'interno di un ciclo

La maggior parte degli iteratori produce valori all'interno di un ciclo. Qui si generano i primi count numeri pari senza allocare alcuna raccolta.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Evens(int count)
    {
        for (int i = 0; i < count; i++)
            yield return i * 2;
    }

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

Il metodo restituisce IEnumerable

Un metodo iteratore deve restituire IEnumerable<T> o IEnumerator<T>, oppure le versioni non generiche. Non si scrive mai return con un valore; si usa soltanto yield return.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<string> Greetings()
    {
        yield return "hello";
        yield return "hi";
        yield return "hey";
    }

    public static void Main()
    {
        foreach (var g in Greetings())
            Console.WriteLine(g);
    }
}

L'esecuzione viene sospesa e ripresa

Lo stato tra un yield e l'altro viene conservato automaticamente. Le variabili locali mantengono i propri valori durante le pause, rendendo molto semplice generare totali progressivi.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> RunningTotal(IEnumerable<int> nums)
    {
        int total = 0;
        foreach (var n in nums)
        {
            total += n;
            yield return total;
        }
    }

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

Generare sequenze infinite

Poiché i valori vengono prodotti su richiesta, un iteratore può descrivere in modo sicuro una sequenza infinita. È il chiamante a decidere quando smettere di richiedere valori.

using System;
using System.Collections.Generic;

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

    public static void Main()
    {
        int taken = 0;
        foreach (var n in Naturals())
        {
            Console.WriteLine(n);
            if (++taken == 5) break;
        }
    }
}

Trasformare una sequenza di input

Gli iteratori sono ideali per creare pipeline: leggono gli elementi da una sequenza, li trasformano e restituiscono i risultati in modo differito.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<string> Labelled(IEnumerable<int> nums)
    {
        foreach (var n in nums)
            yield return "item-" + n;
    }

    public static void Main()
    {
        foreach (var s in Labelled(new[] { 10, 20, 30 }))
            Console.WriteLine(s);
    }
}

Filtrare con gli iteratori

Per filtrare, è sufficiente restituire solo gli elementi desiderati. Gli elementi ignorati non vengono mai prodotti, quindi il codice a valle non li vede.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> OnlyPositive(IEnumerable<int> nums)
    {
        foreach (var n in nums)
            if (n > 0) yield return n;
    }

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

Il compilatore crea una macchina a stati

Dietro le quinte, il compilatore riscrive l'iteratore trasformandolo in una classe che implementa IEnumerator<T>, tenendo traccia di un campo di stato nascosto e di un valore Current. Tutto questo meccanismo è disponibile automaticamente.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<char> Letters()
    {
        yield return 'a';
        yield return 'b';
        yield return 'c';
    }

    public static void Main()
    {
        IEnumerator<char> e = Letters().GetEnumerator();
        while (e.MoveNext())
            Console.WriteLine(e.Current);
    }
}

Comporre più iteratori

Gli iteratori si concatenano naturalmente perché ciascuno restituisce un IEnumerable<T>. Si può passare l'output di un iteratore a quello successivo per creare pipeline leggibili.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Range(int start, int count)
    {
        for (int i = 0; i < count; i++) yield return start + i;
    }
    static IEnumerable<int> Squares(IEnumerable<int> nums)
    {
        foreach (var n in nums) yield return n * n;
    }

    public static void Main()
    {
        foreach (var n in Squares(Range(1, 4)))
            Console.WriteLine(n);
    }
}

Provi personalmente

Scriva un iteratore che raggruppi una sequenza di input in blocchi di dimensione fissa. Restituisce liste su richiesta e mostra quanta logica può essere contenuta in un singolo iteratore ben strutturato.

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<List<int>> Batch(IEnumerable<int> source, int size)
    {
        var bucket = new List<int>();
        foreach (var n in source)
        {
            bucket.Add(n);
            if (bucket.Count == size) { yield return bucket; bucket = new List<int>(); }
        }
        if (bucket.Count > 0) yield return bucket;
    }

    public static void Main()
    {
        foreach (var group in Batch(new[] { 1, 2, 3, 4, 5 }, 2))
            Console.WriteLine(string.Join(",", group));
    }
}

Verifica rapida

Richiami il funzionamento dei metodi iteratori.

Riepilogo

I metodi iteratori usano yield return per produrre sequenze su richiesta.

  • Il metodo restituisce IEnumerable<T> o IEnumerator<T>.
  • Ogni yield return emette un valore e mette in pausa l'esecuzione, preservando lo stato locale.
  • Possono descrivere in modo sicuro sequenze infinite.
  • Il compilatore genera automaticamente la macchina a stati.

Domande Frequenti

La lezione «Metodi iteratori con yield return» è gratuita?

Sì — il testo completo di «Metodi iteratori con yield return» è 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 «Metodi iteratori con yield return»?

Generi sequenze un elemento alla volta. 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 1 di 4.

Quanto tempo richiede la lezione «Metodi iteratori con yield return»?

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